彻底理解线程同步与同步代码块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对象。

这就是互相等待。

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

原文地址:https://www.cnblogs.com/sgzs/p/7943647.html