2015-11-03 112 views
0

我有一个名为MyRunnable类:为什么此同步方法无法按预期工作?

public class MyRunnable extends Main implements Runnable { 
    String name; // name of thread 
    Thread t; 

    MyRunnable (String threadname) { 
     name = threadname; 
     t = new Thread(this, name); 
     t.start(); 
    } 

    public void run() { 
     try { 
      for (int i=0;i<100000;i++) { 
       extend(1); 
      } 
     } catch (InterruptedException e) { 
      System.out.println("Thread interrupted."); 
     } 
     System.out.println("Thread " + name + " exiting."); 
    } 

} 

和一个名为Main类:

public class Main { 
    private static List<Integer> numbers=new ArrayList<>(); 

    public synchronized void extend (int i) throws InterruptedException { 
     numbers.add(i); 
    } 
    public synchronized static int getSize() { 
     return numbers.size(); 
    } 

    public static void main(String[] args) { 
     MyRunnable t0=new MyRunnable("0"); 
     MyRunnable t1=new MyRunnable("1"); 
     MyRunnable t2=new MyRunnable("2"); 

     try { 
      t0.t.join(); 
      t1.t.join(); 
      t2.t.join(); 
     } catch (InterruptedException e) { 

     } 
     System.out.println(getSize()); 
    } 
} 

现在我会期望得到30万作为输出,而是我得到一个随机数(约之间250000和290000),尽管我确实使用了同步方法。我没看过oracle的文档http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html,但我似乎无法弄清楚为什么这不能按预期工作。有人能解释我为什么吗?

预先感谢

+1

您正在创建三个'MyRunnable'实例。每个都在同步。 –

回答

1

方法被同步到调用它们的对象。您需要创建一个在每个对象之间共享的对象,并让它们在该对象上同步。

private static List<Integer> numbers=new ArrayList<>(); 
public synchronized void extend (int i) throws InterruptedException { 
    synchronize(numbers) { 
     numbers.add(i); 
    } 
} 
1

​​这里锁定抵靠该方法extend被调用的对象(因为它是一个实例方法)。因此,您正在同步三个不同的对象。

如果您在共享的static列表中同步(例如),则会得到预期的结果。

相关问题