2013-02-24 106 views
-1

在下面的代码中,如果我同步bar方法,它在输出方面没有什么不同 - 我做错了什么?我相信同步“栏”会使“ThreaOne”被打印10次,然后只打印“ThreadTwo”将开始,但事实并非如此。我得到的输出中如下:简单的线程同步问题


 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread OneOneOneOne 
I am in main now 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread OneOneOneOne 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am Test thread:Thread Two 
I am in main now 

等。这里是我的代码:

package com.rahul; 

class ThreadTest implements Runnable{ 
    @Override 
    public void run() { 
     bar(); 
    } 
    public synchronized void bar() { 
     for(int i=0;i<10;i++){ 
      System.out.println("I am Test thread:"+Thread.currentThread().getName()); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 
} 

public class Test{ 
    public static void main(String[] args) { 
     Thread t1 = new Thread(new ThreadTest(),"Thread OneOneOneOne"); 
     Thread t2 = new Thread(new ThreadTest(),"Thread Two"); 
     t1.start(); 
     try{ 
      Thread.sleep(4000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     t2.start(); 
     while(true){ 
      System.out.println("I am in main now"); 
      try { 
       t2.join(); 
       Thread.sleep(4000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

回答

3

你有两个实例ThreadTest。他们没有任何关系,你不调用同一个bar()

如果你这样做,而不是:

ThreadTest tt = new ThreadTest(); 
Thread t1 = new Thread(tt,"Thread OneOneOneOne"); 
Thread t2 = new Thread(tt,"Thread Two"); 

然后两个线程共享的ThreadTest一个实例,并只有一个线程将能够在一个时间打电话bar()单个实例。

+0

该死的,我错过了。非常感谢Brian! – user1291291 2013-02-24 07:32:35

2

声明该方法为​​不会产生您所期望的效果。每个线程在它自己的实例ThreadTest上同步,因此这些调用不会相互影响。您需要在共享对象上同步一个线程才能阻止另一个线程。例如:

class ThreadTest implements Runnable{ 
    private static Object LOCK_OBJECT = new Object(); 
    @Override 
    public void run() { 
     bar(); 
    } 
    public void bar() { 
     synchronized (LOCK_OBJECT) { 
      for(int i=0;i<10;i++){ 
       System.out.println("I am Test thread:"+Thread.currentThread().getName()); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
0

你同步是由只有一个线程访问,因为它们是实例方法,所以每个线程是调用它的自己杆法的方法。

也许你想声明栏方法为static