2015-08-17 62 views
2

我难以理解​​和重入锁。这里是小程序,我是用实验:这些线程为什么不按顺序运行?

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Reentr { 

    public static void main(String[] args) { 
     ExecutorService eService = Executors.newFixedThreadPool(2); 
     for (int i = 1; i <= 2; i++) { 
      eService.execute(new process()); 
     } 

     try { 
      Thread.sleep(1); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     eService.shutdown(); 
    } 

} 

class process implements Runnable { 
    int count = 0; 

    @Override 
    public void run() { 

     processTest(); 
    } 

    public synchronized void processTest() { 
     try { 
      for (int i = 1; i <= 2; i++) { 
       count += i; 
       System.out.println("count value for " + Thread.currentThread().getName() + " is " + count); 
      } 
     } finally { 
      System.out.println("count for " + Thread.currentThread().getName() + " is " + count); 
     } 
    } 

} 

产量为:

count value for pool-1-thread-2 is 1 
count value for pool-1-thread-1 is 1 
count value for pool-1-thread-2 is 3 
count for pool-1-thread-2 is 3 
count value for pool-1-thread-1 is 3 
count for pool-1-thread-1 is 3 

如果我们在输出的两个线程看到在synchronized块。我的印象是一个线程必须完成synchronized方法的执行,然后其他线程才会进入方法。

理想情况下,我期待结果是这样的

count value for pool-1-thread-1 is 1 
count value for pool-1-thread-1 is 3 
count for pool-1-thread-1 is 3 
count value for pool-1-thread-2 is 1 
count value for pool-1-thread-2 is 3 
count for pool-1-thread-2 is 3 

我已经替换为同步块和重入锁同步方法。但是,我仍然有相同的输出。我错过了什么?

+0

您每次都有新的''process'实例。他们的关键部分没有争议。 – Keith

回答

1

两个线程在同一个对象上不同步。

你有process两个不同的实例(顺便说一句,你应该总是命名以大写字母类)。如果你想一个线程后,其他运行

public void processTest() { 
    synchronized(this) { 
    // etc.. 
    } 
} 

,他们必须在同一对象上进行同步:在​​关键字相当于。如果你这样做,例如:

class process implements Runnable { 
    // note that this is static 
    private static final Object lock = new Object(); 

    public void processTest() { 
    synchronized(lock) { 
     // your code 
    } 
    } 
} 

然后你的代码将有一个线程运行在另一个之后。另一种方法是将锁传入Object的构造函数或Semaphore的相同实例等。

+0

感谢您的回应..我错过了我每次都在创建新对象 – prred

1

当声明实例方法​​时,它在对象实例上同步。由于您在每个循环迭代中运行new process(),因此对象实例不同,因此同步无意义。尝试创建一个单一的process对象,并将其传递给您启动的两个线程。

当您这样做时,还会将count实例变量移动到processTest方法中。这样它将是线程安全的。

+0

感谢您的回复..我错过了我每次创建新对象 – prred

相关问题