在学习多线程的过程中,很多资料都会指出synchronized代码块和synchronized方法使用的锁都是this ,静态synchronized方法使用的锁是类锁,那么从这个结论出发,如何进行逆向证明呢?
证明this锁
``
public class ThreadDemo3 { public static void main(String[] args) throws InterruptedException{ MyThread3 mt = new MyThread3(); Thread t1 = new Thread(mt, "窗口1"); Thread t2 = new Thread(mt, "窗口2"); t1.start(); Thread.sleep(40); mt.flag = false; t2.start(); }}?class MyThread3 implements Runnable { int tickets = 100; boolean flag = true; Object obj = new Object();? public void run() { if (flag) { while (tickets > 0) { synchronized (obj) { if (tickets > 0) { try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "售出了" + (100 - tickets + 1) + "张票"); tickets--; } } } } else { while (tickets > 0) { sell(); } } }? synchronized public void sell() { if (tickets > 0) { try { Thread.sleep(40); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "售出了" + (100 - tickets + 1) +"张票"); tickets--; } }}
代码如上,简单说明下思路,synchronized同步代码块用obj作为锁的时候,打印的结果:两个线程随机打印,从第1张票卖到101张,说明出现了线程不安全问题,从而可以得出线程t1和t2没有同步执行的结论;
再把同步代码块中的锁改成this对象,再次执行,打印的结果为:两个线程随机打印,从第1张票卖到100张。
证明类锁
把上面的代码再稍作修改,将sell方法,flag对象,tickets对象加上static修饰符,再次运行代码,可以看到结果又打印了101张票,说明静态方法使用的并非this锁,我们根据结论,把synchronized同步代码块里的锁换成"MyThread3.class"再运行程序,同步现象出现!
这样一来就可以验证开头的结论了
做个小总结,在写这段代码的过程中,犯了一个问题,把while循环写到了synchronized代码块中,这样做会导致线程同步以后,变成单线程执行,线程t2永远不会获得执行的机会!!所以一定要注意在多线程编码过程中,同步代码块的范围
原文地址:https://www.cnblogs.com/blogforvi/p/12164225.html
时间: 2024-08-27 14:02:50