- Java并发编程(1):可重入内置锁
- Java并发编程(2):线程中断(含代码)
- Java并发编程(3):线程挂起、恢复与终止的正确方法(含代码)
- Java并发编程(4):守护线程与线程阻塞的四种情况
- Java并发编程(5):volatile变量修饰符—意料之外的问题(含代码)
- Java并发编程(6):Runnable和Thread实现多线程的区别(含代码)
- Java并发编程(7):使用synchronized获取互斥锁的几点说明
- Java并发编程(8):多线程环境中安全使用集合API(含代码)
- Java并发编程(9):死锁(含代码)
- Java并发编程(10):使用wait/notify/notifyAll实现线程间通信的几点重要说明
- Java并发编程(11):线程间通信中notify通知的遗漏(含代码)
- Java并发编程(12):线程间通信中notifyAll造成的早期通知问题(含代码)
- Java并发编程(13):生产者—消费者模型(含代码)
- Java并发编程(14):图文讲述同步的另一个重要功能—内存可见性
- Java并发编程(15):并发编程中实现内存可见的两种方法比较—加锁和volatile变量
- Java并发编程(16):深入Java内存模型—happen-before规则及其对DCL的分析(含代码)
- Java并发编程(17):深入Java内存模型—内存操作规则总结
- Java并发编程(18):第五篇中volatile意外问题的正确分析解答(含代码)
- Java并发编程(19):并发新特性—Executor框架与线程池(含代码)
- Java并发编程(20):并发新特性—Lock锁和条件变量(含代码)
-
【Java并发编程之深入理解】Synchronized的使用
2018-09-08 20:56:16在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的...
1.为什么要使用synchronized
在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。2.实现原理
synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性3.synchronized的三种应用方式
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:- 普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
- 静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
- 同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
4.synchronized的作用
Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码
5.举栗子
**一、synchronized作用于实例方法** ①多个线程访问同一个对象的同一个方法
public class synchronizedTest implements Runnable { //共享资源 static int i =0; /** * synchronized 修饰实例方法 */ public synchronized void increase(){ i++; } @Override public void run(){ for (int j =0 ; j<10000;j++){ increase(); } } public static void main(String[] args) throws InterruptedException { synchronizedTest test = new synchronizedTest(); Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
结果:
分析:当两个线程同时对一个对象的一个方法进行操作,只有一个线程能够抢到锁。因为一个对象只有一把锁,一个线程获取了该对象的锁之后,其他线程无法获取该对象的锁,就不能访问该对象的其他synchronized实例方法,需要等到对象被释放后才能获取,但是在对象没有被释放前,其他线程可以访问非synchronized修饰的方法②一个线程获取了该对象的锁之后,其他线程来访问其他synchronized实例方法现象 举栗
public class SynchronizedTest { public synchronized void method1() { System.out.println("Method 1 start"); try { System.out.println("Method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 1 end"); } public synchronized void method2() { System.out.println("Method 2 start"); try { System.out.println("Method 2 execute"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 2 end"); } public static void main(String[] args) { final SynchronizedTest test = new SynchronizedTest(); new Thread(test::method1).start(); new Thread(test::method2).start(); } }
结果:
分析:可以看出其他线程来访问synchronized修饰的其他方法时需要等待线程1先把锁释放③一个线程获取了该对象的锁之后,其他线程来访问其他非synchronized实例方法现象 举栗
去掉②中方法二的synchronizedpublic class SynchronizedTest { public synchronized void method1() { System.out.println("Method 1 start"); try { System.out.println("Method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 1 end"); } public void method2() { System.out.println("Method 2 start"); try { System.out.println("Method 2 execute"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 2 end"); } public static void main(String[] args) { final SynchronizedTest test = new SynchronizedTest(); new Thread(test::method1).start(); new Thread(test::method2).start(); } }
结果:
分析:当线程1还在执行时,线程2也执行了,所以当其他线程来访问非synchronized修饰的方法时是可以访问的④当多个线程作用于不同的对象
public class SynchronizedTest { public synchronized void method1() { System.out.println("Method 1 start"); try { System.out.println("Method 1 execute"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 1 end"); } public synchronized void method2() { System.out.println("Method 2 start"); try { System.out.println("Method 2 execute"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Method 2 end"); } public static void main(String[] args) { final SynchronizedTest test1 = new SynchronizedTest(); final SynchronizedTest test2 = new SynchronizedTest(); new Thread(test1::method1).start(); new Thread(test2::method2).start(); } }
结果:
分析:因为两个线程作用于不同的对象,获得的是不同的锁,所以互相并不影响**此处思考一个问题:为什么分布式环境下synchronized失效?如何解决这种情况?** **二、synchronized作用于静态方法** public class synchronizedTest implements Runnable { //共享资源 static int i =0; /** * synchronized 修饰实例方法 */ public static synchronized void increase(){ i++; } @Override public void run(){ for (int j =0 ; j<10000;j++){ increase(); } } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new synchronizedTest()); Thread t2 = new Thread(new synchronizedTest()); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); }
结果:
分析:由例子可知,两个线程实例化两个不同的对象,但是访问的方法是静态的,两个线程发生了互斥(即一个线程访问,另一个线程只能等着),因为静态方法是依附于类而不是对象的,当synchronized修饰静态方法时,锁是class对象。**三、synchronized作用于同步代码块** 为什么要同步代码块呢?在某些情况下,我们编写的方法体可能比较大,同时存在一些比较耗时的操作,而需要同步的代码又只有一小部分,如果直接对整个方法进行同步操作,可能会得不偿失,此时我们可以使用同步代码块的方式对需要同步的代码进行包裹,这样就无需对整个方法进行同步操作了。
public class synchronizedTest implements Runnable { static synchronizedTest instance=new synchronizedTest(); static int i=0; @Override public void run() { //省略其他耗时操作.... //使用同步代码块对变量i进行同步操作,锁对象为instance synchronized(instance){ for(int j=0;j<10000;j++){ i++; } } } public static void main(String[] args) throws InterruptedException { Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
结果:
分析:将synchronized作用于一个给定的实例对象instance,即当前实例对象就是锁对象,每次当线程进入synchronized包裹的代码块时就会要求当前线程持有instance实例对象锁,如果当前有其他线程正持有该对象锁,那么新到的线程就必须等待,这样也就保证了每次只有一个线程执行i++;操作。当然除了instance作为对象外,我们还可以使用this对象(代表当前实例)或者当前类的class对象作为锁,如下代码://this,当前实例对象锁 synchronized(this){ for(int j=0;j<1000000;j++){ i++; } } //class对象锁 synchronized(AccountingSync.class){ for(int j=0;j<1000000;j++){ i++; } }
-
Java 并发编程
2020-12-11 11:25:02Java并发编程系列: > Java 并发编程:核心理论 > Java并发编程:Synchronized及其实现原理 > Java并发编程:Synchronized底层优化(轻量级锁、偏向锁) > Java 并发编程:线程间的协作(wait/notify/... -
java并发编程
2017-01-17 14:37:14为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅入深的学习顺序总结如下,点击相应的标题即可跳转到对应的文章 【Java并发编程】实现多线程的两种方法 【Java...为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅入深的学习顺序总结如下,点击相应的标题即可跳转到对应的文章
【Java并发编程】synchronized的另个一重要作用:内存可见性
【Java并发编程】实现内存可见性的两种方法比较:synchronized和Volatile
【Java并发编程】线程间协作:wait、notify、notifyAll
【Java并发编程】深入Java内存模型(1)——happen—before规则及其对DCL问题的分析
【Java并发编程】深入Java内存模型(2)——内存操作规则总结
【Java并发编程】并发新特性—Executor框架与线程池
【Java并发编程】并发新特性—障碍器CyclicBarrier
为了方便各位网友学习以及方便自己复习之用,将Java并发编程系列内容系列内容按照由浅入深的学习顺序总结如下,点击相应的标题即可跳转到对应的文章
【Java并发编程】synchronized的另个一重要作用:内存可见性
【Java并发编程】实现内存可见性的两种方法比较:synchronized和Volatile
【Java并发编程】线程间协作:wait、notify、notifyAll
【Java并发编程】深入Java内存模型(1)——happen—before规则及其对DCL问题的分析
【Java并发编程】深入Java内存模型(2)——内存操作规则总结
【Java并发编程】并发新特性—Executor框架与线程池
-
Java并发编程
2016-07-26 15:30:09Java并发编程(1):可重入内置锁Java并发编程(2):线程中断(含代码)Java并发编程(3):线程挂起、恢复与终止的正确方法(含代码)Java并发编程(4):守护线程与线程阻塞的四种情况Java并发编程(5):... -
JAVA并发编程
2015-06-26 16:01:08书籍:JAVA并发编程实践 http://vdisk.weibo.com/s/aP04X7rRcCoks 2 提纲 并发程序能够提高多核处理器利用率,加快响应。即便是单核的情况下,并发程序也能有效的提高性能。和并发编程对应的是顺序编程, -
Java并发编程 - 第四章 Java并发编程基础
2020-08-25 15:15:39本章将着重介绍Java并发编程的基础知识,从启动一个线程到线程间不同的通信方式,最后通过简单的线程池示例以及应用(简单的 Web 服务器)来串联本章所介绍的内容。 一、线程简介 1.1 什么是线程 现代操作系统在运行... -
Java并发编程艺术
2018-01-03 21:25:04Java并发编程艺术Java并发编程艺术Java并发编程艺术Java并发编程艺术Java并发编程艺术 -
JAVA并发编程实践
2018-07-31 16:54:38JAVA并发编程实践 JAVA并发编程实践 JAVA并发编程实践 -
Java并发编程之美 、 Java并发编程的艺术 、实战Java高并发程序设计 这三本书哪本好一点
2019-08-06 00:39:07Java并发编程之美 、Java并发编程的艺术 、 实战Java高并发程序设计 这三本书哪本好一点 感觉都差不多 哪本适合找实习的大学生 -
java并发编程2
2019-02-15 09:57:38java并发编程pdf文档第二部分:Java并发编程实战.pdf、Java多线程编程核心技术.pdf、实战Java高并发程序设计.pdf -
Java并发编程实战
2020-05-28 16:33:33同时,课程还会深入介绍Java并发编程技术背后的逻辑关系以及应用场景,助你能够游刃有余地游走在这些技术之中。 课程核心知识点: 1. 线程安全性分析,主要内容包括原子性、可见性、有序性等... -
【Java并发编程】并发编程大合集
2018-11-06 23:07:38【Java并发编程】实现多线程的两种方法 【Java并发编程】线程的中断 【Java并发编程】正确挂起、恢复、终止线程 【Java并发编程】守护线程和线程阻塞 【Java并发编程】Volatile关键字(上) 【Java并发编程】... -
java 并发编程
2015-11-03 18:24:31线程的概念 关于线程安全 java thread中的wait()和notify() java synchronized Java 线程池 Java线程池相关类 Java 并发包之BlockingQueue 本列表会不断更新 -
Java并发编程对比Actor并发编程
2020-03-02 21:57:46在Java并发编程中,每个对象都有一个逻辑监视器(monitor),可以用来控制对象的多线程访问。我们添加sychronized关键字来标记,需要进行同步加锁访问。这样,通过加锁的机制来确保同一时间只有一... -
大师卡-Java并发编程基础与实战
2020-03-17 18:38:38Java并发编程基础与实战 -
Java并发编程精讲
2019-09-28 15:16:34锁实现和并发容器等高并发Java实现,去深入理解在并发编程中, 一些最容易被忽视的点,这些点也是我在多年编程经验中实际用到, 对于每个小节小课均会有实际的场景应用为你呈现。 同时这些也是面试过程中面试官... -
JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程
2019-04-01 09:48:53JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 -
java并发编程面试题
2020-09-28 23:25:464、JVM对Java的原生锁做了哪些优化?5、为什么说Synchronized是非公平锁?6、什么是锁消除和锁粗化?7、为什么说Synchronized是一个悲观锁?乐观锁的实现原理又是什么?什么是CAS,它有什么特性?8、乐观锁一定就是好... -
Java并发编程系列
2018-03-08 17:08:00Java并发编程系列 2018-03-08 Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁、偏向锁) Java 并发编程:线程间的协作... -
Java并发编程九线程池
2019-08-06 16:28:48Java并发编程一:并发基础必知 Java并发编程二:Java中线程 Java并发编程三:volatile使用 Java并发编程四:synchronized和lock Java并发编程五:Atomic原子类 Java并发编程六:并发队列 Java并发编程七:...
-
智联万物,京东IoT技术创新与实践
-
基于Arduino WemosD1的智能感应开盖垃圾桶
-
最新人教版五年级下册语文第二单元基础过关知识整理.doc
-
前端性能优化
-
【数据分析-随到随学】Hadoop数据分析
-
Python+Django+Mysql的多app后端开发入门
-
学生信息管理系统python
-
JQuery03-属性操作,批量操作,attr() prop()
-
最新罗技鼠标宏,直接导入就可用。
-
【数据分析-随到随学】Spark理论及实战
-
前端架构师和3D-VR
-
C++开发提升(1)
-
Python——基于OpenCV的人脸数据、训练、识别.zip
-
Go语言官方文档学习笔记(第六季-一撮金游戏)
-
第1章 Java入门基础及环境搭建【java编程进阶】
-
(新)备战2021软考网络工程师培训学习套餐
-
ObjectARX中文版.chm
-
基于X210的裸机时钟温度显示器-第3/3季
-
变量的定义(C++)
-
MQTT实现SHT20温度传感器定时上传温度值