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  * 所有的非静态同步方法用的都是同一把锁 -- 实例对象本身 (Class)
23  *     所有的静态同步方法用的也是同一把锁 -- 类对象本身   (this)
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 }
时间: 2024-12-07 13:54:54

9.线程八锁的相关文章

【转】线程八锁

package com.java.juc; /** * 题目:判断打印 "one" or "two" * * 1.两个普通同步方法,两个线程 ,标准打印,打印?// one two * 2.新增Thread.sleep(3000) 给getOne() 打印? // 3s 后打印 one two * 3.新增普通方法 getThreee 打印?// 先打印three 三秒后打印 one two * 4.两个普通同步方法,两个number对象,打印? // two 3s

java多线程 -- 线程八锁

一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法 加个普通方法后发现和同步锁无关 换成两个对象后,不是同一把锁了,情况立刻变化. 都换成静态同步方法后,情况又变化 所有的非静态同步方法用的都是同一把锁--实例对象本身,也

(三)juc高级特性——虚假唤醒 / Condition / 按序交替 / ReadWriteLock / 线程八锁

8. 生产者消费者案例-虚假唤醒 参考下面生产者消费者案例: /* * 生产者和消费者案例 */ public class TestProductorAndConsumer { public static void main(String[] args) { Clerk clerk = new Clerk(); Productor pro = new Productor(clerk); Consumer cus = new Consumer(clerk); new Thread(pro, "生产

线程八锁

锁的是当前对象this,被锁定后,其他线程都不能进入到当前对象的其他的synchronized方法. 所有的非静态同步方法用的都是同一把锁 -- 实例对象本身 所有的静态同步方法用的也是同一把锁 -- 类对象本身 /* * 题目:判断打印的 "one" or "two" ? * * 1. 两个普通同步方法,两个线程,标准打印, 打印? //one two * 2. 新增 Thread.sleep() 给 getOne() ,打印? //one two * 3. 新增

11、JUC--线程八锁

线程八锁 • 一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用 其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻 内,只能有唯一一个线程去访问这些synchronized方法 • 锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的 synchronized方法 • 加个普通方法后发现和同步锁无关 • 换成两个对象后,不是同一把锁了,情况立刻变化. • 都换成静态同步方法后,情况又变化 • 所有的非静态同

《Cracking the Coding Interview》——第16章:线程与锁——题目5

2014-04-27 20:16 题目:假设一个类Foo有三个公有的成员方法first().second().third().请用锁的方法来控制调用行为,使得他们的执行循序总是遵从first.second.third的顺序. 解法:你应该想到了用lock的方法类阻塞,不过这里面有个概念问题使得直接用ReentrantLock不能通过编译(对于一个锁对象,不同在A线程中锁定,又在B线程中解锁,不允许这样的归属关系),可以用Semaphore来达到相同的目的.请看下面的代码. 代码: 1 // 16

《Cracking the Coding Interview》——第16章:线程与锁——题目3

2014-04-27 19:26 题目:哲学家吃饭问题,死锁问题经典模型(专门用来黑哲学家的?). 解法:死锁四条件:1. 资源互斥.2. 请求保持.3. 非抢占.4. 循环等待.所以,某砖家拿起一只筷子后如果发现没有另一只了,就必须把手里这只筷子放下,这应该是通过破坏"请求保持"原则来防止死锁产生,请求资源失败时,连自己的资源也进一步释放,然后在下一轮里继续请求,直到成功执行. 代码: 1 // This is the class for chopsticks. 2 import j

《Cracking the Coding Interview》——第16章:线程与锁——题目2

2014-04-27 19:14 题目:如何测量上下文切换的时间? 解法:首先,上下文切换是什么,一搜就知道.对于这么一个极短的时间,要测量的话,可以通过放大N倍的方法.比如:有A和B两件事,并且经常一起发生,每件只需要花几纳秒.如果你把A事件连续做几百万次,而B时间只做了几次,这样就能排除B事件对于测量的影响.如果总时间S = mA + nB.当m >> n 时,A≈S / m.下面的测量方法类似于打乒乓球,在主线程和副线程间互相传递一个令牌,这个令牌可以是变量.管道之类的用于通信的工具.与

《Cracking the Coding Interview》——第16章:线程与锁——题目1

2014-04-27 19:09 题目:线程和进程有什么区别? 解法:理论题,操作系统教材上应该有很详细的解释.我回忆了一下,写了如下几点. 代码: 1 // 16.1 What is the difference between process and thread? 2 Answer: 3 Process: 4 1. Basic element of resource allocation in the operating system. 5 2. Possesses independent