为什么这些线程 运行 不按顺序排列?
Why don't these threads run in sequence?
我很难理解synchronized
和可重入锁。这是我正在试验的小程序:
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方法的执行,之后另一个线程才会进入该方法。
理想情况下,我期待这样的结果
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
我已经用同步块和可重入锁替换了同步方法。但是,我仍然有相同的输出。我错过了什么?
当实例方法被声明时synchronized
,它在对象实例上同步。由于你在每次循环迭代中都是运行一个new process()
,对象实例不一样,所以同步是没有意义的。尝试创建一个 process
对象并将其传递给您启动的两个线程。
执行此操作时,还要将 count
实例变量移动到 processTest
方法中。这样它将是线程安全的。
两个线程没有在同一个对象上同步。
您有两个不同的 process
实例(顺便说一句;您应该始终使用大写字母命名 类)。 synchronized
关键字等同于:
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
s 构造函数,或 Semaphore
的相同实例,等等
我很难理解synchronized
和可重入锁。这是我正在试验的小程序:
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方法的执行,之后另一个线程才会进入该方法。
理想情况下,我期待这样的结果
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
我已经用同步块和可重入锁替换了同步方法。但是,我仍然有相同的输出。我错过了什么?
当实例方法被声明时synchronized
,它在对象实例上同步。由于你在每次循环迭代中都是运行一个new process()
,对象实例不一样,所以同步是没有意义的。尝试创建一个 process
对象并将其传递给您启动的两个线程。
执行此操作时,还要将 count
实例变量移动到 processTest
方法中。这样它将是线程安全的。
两个线程没有在同一个对象上同步。
您有两个不同的 process
实例(顺便说一句;您应该始终使用大写字母命名 类)。 synchronized
关键字等同于:
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
s 构造函数,或 Semaphore
的相同实例,等等