zoukankan      html  css  js  c++  java
  • 一个多线程同步问题

    昨天,路过https://forums.oracle.com/message/10448617的时候,发现了这个问题:

    class SyncClass
    {
         synchronized void synMthd(String s)
         {
              System.out.println("[ "+s);
              try
              {
                   Thread.sleep(3000);
              }
              catch(Exception e)
              {
                   System.out.println(e);
              }
              System.out.println(" ]");
         }
    }
    class Test implements Runnable
    {
         public static void main(String ar[])
         {
              Test tt = new Test();
              Thread t1 = new Thread(tt,"T1");
              Thread t2 = new Thread(tt,"T2");
              t1.start();
              t2.start();
         }
         public void run()
         {
              SyncClass syn = new SyncClass();
              Thread th = Thread.currentThread();
              // synchronized(syn)
           // {
                   syn.synMthd(th.getName());
            // }
         }    
    }   

    输出结果如图: 

    也就是说 synchronized不起作用了,为什么没有实现同步,让下一个线程处于阻塞状态,下面我想就这个问题谈点自己的观点:

    其实

    synchronized void synMthd(String s)

     {          

    System.out.println("[ "+s);          

         try{               

              Thread.sleep(3000);         

         }          

        catch(Exception e)        

       {               

            System.out.println(e);          

        }          

    System.out.println(" ]");     

    }

    代码块确实被锁住了,但是在Thread的run方法中创建了对象SyncClass syn = new SyncClass();

    因为run这个方法或当前对象没有被锁住,也就是说T1和T2两个线程,分别执行run的时候,创建了两个对象,因为SyncClass的Class类没有被锁住,

    所以同时创建了两个对象,当线程T2在调用synMthd(String s)的时候输出 [ T2 ,还没有往

    下走的时候,另外一个线程也执行到了这里,并且调用了另外一个对象的该代码块同一时间输出了[ T1,这样就造成synchronized不起作用的结果。

    如果在run中锁定this,也就是Test的Class类或着修改成:

    public void run() {  

    SyncClass syn = new SyncClass();  

    Thread th = Thread.currentThread();

      synchronized (syn.getClass()) {

       syn.synMthd(th.getName());  

    }

     }

    的使用都可以阻塞下一个线程实现同步的。


        

    钟声敲响了日落
  • 相关阅读:
    SQLServer2008对数据分区
    SQL Server2008 1
    [原创]个人工具 照片信息管理器介绍
    【转】C# 实现用艺术效果显示文本的标签控件
    【转】C#如何让WinForm嵌入桌面窗口最底层
    【转】C#使用GDI+制作背景颜色淡入淡出效果的按钮
    【转】C# WinForm程序添加启动画面
    在C#中使用DataTable存储数据
    无题1
    DataGridView 为TextBox初始化,单击事件
  • 原文地址:https://www.cnblogs.com/SATinnovation/p/3249063.html
Copyright © 2011-2022 走看看