9.线程八锁

                         线程八锁

1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

2、当一个线程访问一个实例对象的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该实例对象中的synchronized(this)同步代码块。

3、当一个线程访问一个实例对象的一个synchronized(this)同步代码块时,其他线程对该对象中 /*所有其它*/ synchronized(this)同步代码块的访问将被阻塞。

4-8

所有的非静态同步方法用的都是同一把锁 -- /*实例对象本身*/, (这也是第三锁 的原因,当一个线程访问 非静态同步方法,就占用了 实例对象这个资源,其他线程,就算访问其他的 同步代码块,因为也需要 实例对象,所以被阻塞)

也就是说如果一个实例对象的 非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取到锁的方法释放锁(该对象)后,才能去获取锁

别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁(对象不同,锁不同),所以不需要等待,自己执行自己的

所有的静态同步方法用的也是同一把锁 -- /*类对象本身 */

所以静态同步方法 和 非静态同步方法之间是不会产生竞争的

但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态方法之间,还是不同实例对象的静态同步方法之间,只要它们是同一个类的实例对象!

 

第三锁的演示:因为 number 和 number2 是不同对象,所以即使 getOne方法 和 getTwo方法 都是同步方法,但是锁资源不一样,

一个是 number  一个是number,所以不受影响,但是如果getOne 或者 getTwo 中有 static的同步方法,同步的那个方法的锁资源就是Number类

 1 /*
 2  * 题目:判断打印的 “one” 还是 “two”
 3  * 1.两个普通同步方法,两个线程,标准打印,打印? //直接 one  two
 4  * 2.新增 Thread.sleep() 给getOne()  ,打印?  //one(睡眠3秒) two
 5  * 3.新增普通方法 getThree() ,打印?   // three one(睡眠三秒) two
 6  * 4.两个不同同步方法,两个Number对象  // two  one
 7  * 5.修改 getOne() 为静态同步方法,  // two one
 8  * 6.修改两个方法均为同步静态方法,一个Number对象   //one two
 9  * 7.一个静态同步方法,一个非静态同步方法,两个 Numbe对象   //two  one
10  * 8.两个静态同步方法,两个Number 对象     //two  one
11  * 
12  * */
13 
14 /* 1-3的解释
15  * 1.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
16  * 2.当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
17  * 3.当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中  /所有其它/  synchronized(this)同步代码块的访问将被阻塞。
18  * */
19 
20 
21 /* 4--8的解释
22  * 所有的非静态同步方法用的都是同一把锁 -- 实例对象本身 (this)
23  *     所有的静态同步方法用的也是同一把锁 -- 类对象本身   (class) 
24  * */
25 
26 
27 public class TestThread8Monitor {
28     public static void main(String[] args) {
29         final Number number = new Number();
30         final Number number2 = new Number();
31         new Thread(new Runnable() {    
32             @Override
33             public void run() {
34                 number.getOne();
35             }
36         }).start();
37         new Thread(new Runnable() {    
38             @Override
39             public void run() {
40                 //number.getTwo();
41                 number2.getTwo();
42             }
43         }).start();
44         /*new Thread(new Runnable() {    
45             @Override
46             public void run() {
47                 number.getThree();
48             }
49         }).start();*/
50     }
51 }
52 
53 class Number {
54     public  synchronized void getOne() {
55         try {
56             Thread.sleep(3000);
57         } catch (InterruptedException e) {
58             // TODO Auto-generated catch block
59             e.printStackTrace();
60         }
61         System.out.println("one");
62     }
63     public  synchronized void getTwo() {
64         System.out.println("two");
65     }
66     
67     /*public void getThree() {
68         System.out.println("three");
69     }*/
70 }
原文地址:https://www.cnblogs.com/xuzekun/p/7429252.html