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

 

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

 

猜你喜欢

转载自www.cnblogs.com/blogforvi/p/12164225.html