彻底理解线程同步与同步代码块synchronized

Posted 时光之书

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了彻底理解线程同步与同步代码块synchronized相关的知识,希望对你有一定的参考价值。

技术分享图片
 1 public class Demo {
 2     public static synchronized void fun1(){
 3     }
 4     public synchronized void fun2(){
 5     }
 6     public static void main(String args[]) throws Exception{
 7         synchronized(xxx) {
 8             
 9         }
10     }
11 }
三种同步类型

 

虽然写法不同,但实际上,只有一种,就是【同步代码块】。这是核心核心核心。同步方法也是同步代码块。

同步就是:一个对象同一时间只能为一个同步代码块服务

同步代码块需要传递的对象(锁对象):就是锁住这个对象,表示这个对象正在为我服务,其他人不能用(非synchronized代码块、方法除外)。

同步方法:就是同步代码块,同步锁对象是this

同步静态方法:就是同步代码块,同步锁对象是类的class对象(Demo类里的静态方法锁对象就是Demo.class)

OK了,这就是同步原理。再说简单点当一个对象被锁住之后,在该代码块之外去使用此对象的方法,只要遇到同步代码块,就会进入等待状态

 

那什么是死锁?死锁必须是多个线程对象才能够产生的。

刚刚不是说了,一个被锁住的对象,外部不能够在去掉用他的synchronized方法了吗,可如果我偏要调用,那么就会等待,所以,死锁就是两个线程对象在同步代码块内互相调用,就会死锁。

举个例子:

 

技术分享图片
 1 public class Demo {
 2     public static Demo a = new Demo();
 3     public static Demo b = new Demo();
 4     public void fun1(){
 5         synchronized(a) {
 6             System.out.println("fun1");
 7             try {
 8                 Thread.sleep(100);
 9             } catch (InterruptedException e) {}
10             b.fun2();
11         }
12     }
13     public void fun2(){
14         synchronized(b) {
15             System.out.println("fun2");
16             try {
17                 Thread.sleep(100);
18             } catch (InterruptedException e) {}
19             a.fun1();
20         }
21     }
22 }
死锁例子

 

(加等待是为了更好的说明问题)

fun1方法中,锁住了a对象,使用b对象。

fun2方法中,锁住了b对象,使用a对象。

这就是互相等待。

你如果使用两个线程去调用这两个方法,就会死锁。

 

以上是关于彻底理解线程同步与同步代码块synchronized的主要内容,如果未能解决你的问题,请参考以下文章

2016/9/25编写java实验报告时对synchronized(同步代码块)的一些感悟

深入理解Java中的同步静态方法和synchronized(class)代码块的类锁

java 同步代码块与同步方法

Java线程同步synchronized方法与方法块

synchronized(this) 与 synchronized(class) 理解

线程同步synchronized,Class与Object