我创建了两个可运行的作业:PrintEvenNumbersJob 和 PrintOddNumbersJob,并生成了两个线程来执行这些作业。这似乎工作得很好!但我对这个实现感到有些可疑。我可以对此实现有一些意见和建议吗?
我在这个实现中看到的问题是,只有当 thread1 首先获得对象锁的锁时,程序才会终止,否则它会打印奇数第一偶数第二顺序,并且不会终止,除非我在 PrintEvenNumbersJob 中的 for 语句之后提供另一个语句“lock.notify”(如本实现中所示)。我的问题是如何确保 thread1 首先执行。
public class PrintEvenNumbersJob implements Runnable {
private Object lock;
public PrintEvenNumbersJob(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i <= 10; i += 2) {
lock.notify();
System.out.println(i);
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify(); // not required if thread1 gains lock first
}
}
}
public class PrintOddNumbersJob implements Runnable {
private Object lock;
public PrintOddNumbersJob(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized (lock) {
for (int i = 1; i < 10; i += 2) {
lock.notify();
System.out.println(i);
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock.notify();
}
}
}
public class EvenOddManager {
public static void main(String[] args) {
Object lock = new Object();
PrintEvenNumbersJob printEvenNumbersJob = new PrintEvenNumbersJob(lock);
PrintOddNumbersJob printOddNumbersJob = new PrintOddNumbersJob(lock);
Thread thread1 = new Thread(printEvenNumbersJob);
Thread thread2 = new Thread(printOddNumbersJob);
thread2.start();
thread1.start();
}
}
最佳答案
您尝试过使用信号量吗?这更容易,因为你不需要担心 wait 和 notification 的调用顺序(如果你在 wait 之前调用 notification,它就会“丢失”)
示例代码:
import java.util.concurrent.*;
public class Test {
private final Semaphore oddJobPermits = new Semaphore(0);
private final Semaphore evenJobPermits = new Semaphore(1);
private class EvenJob implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
try {
evenJobPermits.acquire();
System.out.println(i * 2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
oddJobPermits.release();
}
}
}
}
private class OddJob implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
try {
oddJobPermits.acquire();
System.out.println(i * 2 + 1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
evenJobPermits.release();
}
}
}
}
public void run() {
new Thread(new EvenJob()).start();
new Thread(new OddJob()).start();
}
public static void main(String[] args) {
new Test().run();
}
}
关于java - 如何确保打印偶数奇数的两个线程在此实现中保持先偶后奇的顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22976412/