多线程:synchronized代码块、synchronized方法、静态synchronized方法使用的锁

浪尽此生 提交于 2020-01-07 23:27:29

 

在学习多线程的过程中,很多资料都会指出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永远不会获得执行的机会!!所以一定要注意在多线程编码过程中,同步代码块的范围

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!