多线程synchronized, wait, notify, sleep 理解

最近在看多线程,参考了一篇 博客 ,觉得写得比较好,但是在一段相关对象锁的代码上卡住了,理解不了,问了同学,加上自己的理解,终于搞懂了。

测试代码
package com.fehead.test;
import com.fehead.thread.MyThreadPrinter;

public class Test {

	public static void main(String[] args) throws Exception {
		Object a = new Object();
		Object b = new Object();
		Object c = new Object();
		MyThreadPrinter pa = new MyThreadPrinter("A", c, a);
		MyThreadPrinter pb = new MyThreadPrinter("B", a, b);
		MyThreadPrinter pc = new MyThreadPrinter("C", b, c);
		
		new Thread(pa).start();
		Thread.sleep(100);
		new Thread(pb).start();
		Thread.sleep(100);
		new Thread(pc).start();
		Thread.sleep(100);
	}

}

package com.fehead.thread;

public class MyThreadPrinter implements Runnable {
	private String name;
	private Object prev;
	private Object self;
	
	public MyThreadPrinter(String name, Object prev, Object self) {
		this.name = name;
		this.prev = prev;
		this.self = self;
	}
	
	@Override
	public void run() {
		int count = 10;
		while(count > 0) {
			
			synchronized (prev) {
				
				synchronized (self) {
					System.out.print(name);
					count--;
					
					self.notify();
				}
				try {
					prev.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
	
}

输出结果
  • ABCABCABCABCABCABCABCABCABCABC
个人理解
  • sleep() 开始,Thread.sleep(100);能让线程暂停100ms,可以看到线程pa没有线程休眠,线程pb休眠了100ms,而线程pc休眠了200ms(至于第三个Thread.sleep(100);有什么作用我还没搞懂,欢迎大神留言解惑)。

  • 对象锁,顾名思义,实际上是一把锁,wait()是锁,而prev,self(对象a,b,c)是锁孔的形状,相对的notify()是钥匙,与之对应的prev,self(对象a,b,c)是钥匙的形状。

  • 回到代码

    1. 首先开始的是pa同学,他先拿起了c锁,然后又拿起了a锁,用钥匙打开了a锁(虽然a锁并没有锁住任何东西···),接着放下了a锁,用c锁把自己锁住了,最后放下了c锁;
    2. 接下来是pb同学,他一上来就要拿a锁,(但是pa比他快了一步,所以他只能等pa放下a锁后再拿a1), 接着他有拿到了b锁,用钥匙打开了b锁(虽然b锁也没有锁住任何东西···),接着放下了b锁,用a锁把自己锁住了,最后放下了a锁;
    3. 最后是pc同学,他先拿起了b锁,然后又拿起了c锁,用钥匙打开了c锁,还记的用c锁把自己锁起来的pa吧,这个时候他就被放了出来,所以他又开始行动了,接着pc放下了c锁,用b锁把自己锁住了,最后放下了b锁;
    4. 话说papc放出来了,他又拿起了c锁,然后又拿起了a锁,用钥匙打开了a锁(a锁原本锁住的pb被放了出来),接着放下了a锁,用c锁把自己锁住了,最后放下了c锁;
    5. 话说pbpa放出来了,他又拿起了a锁,然后又拿起了b锁,用钥匙打开了b锁(b锁原本锁住的pc被放了出来),接着放下了b锁,用a锁把自己锁住了,最后放下了a锁;
    6. ······
    7. 如此往复,因为while()循环了10次,因此顺序输出ABC10次。
  • 图片理解
    模型理解

理解错误

我在理解对象锁的时候有过一个错误,认为每一个对象锁对应一个线程,a对应pab对应pbc对应pc,实际上wait()是使本线程休眠,也就是不管是哪个对象锁,运行wait()锁住的一定是本线程。


因为是个人理解,所以不一定正确,如果有错误,欢迎大佬指正。


  1. 这句话是为了说明不同的线程不能同时调用同一个对象锁 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值