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

     

  • 相关阅读:
    Oracle VM Virtualbox基础知识
    Ubuntu12.10下Python(pyodbc)访问SQL Server解决方案
    制作系统启动盘重装系统
    仪表·使用相关
    Linux·命令收藏
    串口·相关文章
    Linux命令集锦之·字符截取命令
    Linux命令集锦之·正则表达式
    C#·好文分享
    三大操作系统对比使用之·Ubuntu16.04
  • 原文地址:https://www.cnblogs.com/blogforvi/p/12164225.html
Copyright © 2020-2023  润新知