synchronized 关键字

 关键字 synchronized 获取的锁都是对象锁 , 而不是把一段代码 (方法) 当作锁 , 代码中哪个线程先执行 synchronized 关键字修饰的方法 , 哪个线程就持有该方法所属对象的锁 , 两个对象获取的就是两个不同的锁 , 互不干扰。

有一种情况则是相同的锁 , 即在静态方法上加 synchronized 关键字 , 表示锁定 .class 类 , 类一级别的锁 (独占 .class 类)。

 1 package com.itdoc.multi.sync002;
 2 
 3 /**
 4  * 关键字 synchronized 获取的锁都是对象锁, 而不是把一段代码 (方法) 当作锁,
 5  * 代码中哪个线程先执行 synchronized 关键字修饰的方法, 哪个线程就持有该方法所属对象的锁, 两个对象获取的就是两个不同的锁, 互不干扰。
 6  *
 7  * synchronized 关键字修饰静态方法, 标识锁定 .class 类, 类一级别的锁 (独占 .class 类)
 8  * @author Wáng Chéng Dá
 9  * @create 2017-03-20 8:24
10  */
11 public class MultiThread {
12 
13     private static int num = 0;
14 
15     public static synchronized void pointNum(String tag) {
16         try {
17             if ("a".equals(tag)) {
18                 num = 100;
19                 System.out.println(Thread.currentThread().getName() + " -->> tag is a , set num over!");
20                 Thread.sleep(4000);
21             } else {
22                 num = 200;
23                 System.out.println(Thread.currentThread().getName() + " -->> tag is b , set num over!" );
24             }
25             System.out.println(Thread.currentThread().getName() + " -->> tag : " + tag + ", num = " + num);
26         } catch (InterruptedException e) {
27             e.printStackTrace();
28         }
29     }
30 
31     public static void main(String[] args) {
32 
33         //创建两个不同的对象
34         final MultiThread m1 = new MultiThread();
35         final MultiThread m2 = new MultiThread();
36 
37         Thread t1 = new Thread(new Runnable() {
38             @Override
39             public void run() {
40                 m1.pointNum("a");
41 //                m2.pointNum("b");
42             }
43         }, "t1");
44 
45         Thread t2 = new Thread(new Runnable() {
46             @Override
47             public void run() {
48 //                m1.pointNum("b");
49                 m2.pointNum("b");
50             }
51         }, "t2");
52         t1.start();
53         t2.start();
54     }
55 }
  asynchronized synchronized static synchronized 分析
相同线程相同对象

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

按顺序执行,不存在相互干扰问题。
相同线程不同对象

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is b , set num over!

t1 -->> tag : b, num = 200

按顺序执行,不存在相互干扰问题
不同线程相同对象

t1 -->> tag is a , set num over!

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

------------sleep 4 s-------------

t1 -->> tag : a, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

不用 synchronized 修饰时,线程是不安全的,线程 t1 执行过程中,t2 线程也开始执行这段代码,在 t1 线程睡眠时,t2 线程执行完成将 num 值更改,所以 t1 线程也打印 t2 修改后的结果。添加修饰时,在 t1 线程完成释放锁后 t2 线程才开始执行。
不同线程不同对象

t1 -->> tag is a , set num over!

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is a , set num over!

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t1 -->> tag is a , set num over!

------------sleep 4 s-------------

t1 -->> tag : a, num = 100

t2 -->> tag is b , set num over!

t2 -->> tag : b, num = 200

无修饰和 synchronized 修饰时,不存在相互干扰问题,在 t1 线程执行当中,t2 线程也会执行,运行行为也是正常的。static synchronized 修饰时,只有t1线程执行完成释放锁之后 t2 线程才开始执行。这时候是类一级别的锁。
原文地址:https://www.cnblogs.com/chinda/p/6586973.html