我创建了两个可运行的作业:PrintEvenNumbersJob 和 PrintOddNumbersJob,并生成了两个线程来执行这些作业。这似乎工作得很好!但我对这个实施感到有些可疑。我可以对这个实施有一些意见和建议吗?
我在这个实现中看到的问题是,只有当 thread1 首先获得对象锁的锁时,程序才会终止,否则它会打印奇数第一偶数第二顺序,并且不会终止,除非我在之后提供另一个语句“lock.notify” PrintEvenNumbersJob 中的 for 语句(如本实现中所示)。我的问题是如何确保 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();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)