3 回答
TA贡献1811条经验 获得超5个赞
您需要两个线程之间的一些信号。放置synchronized
方法print
只是保证一次只有一个线程可以进入该方法。可以使用您的线程Object.wait()
和方法。Object.notify{All}()
实际上这是某种Sender-Receiver Synchronization Problem。我调整了您的代码。另外我使用了ExecutorService
andCallable
而不是 extending Thread
,这是不好的做法:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddExample {
private static boolean evensTurn = true;
private static Object monitor = new Object();
public static void print(int i, String name) {
System.out.println(i + "--->" + name);
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(new OddCallable());
executorService.shutdown();
}
public static class EvenCallable implements Callable<Void> {
@Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
synchronized (monitor) {
while (!evensTurn) { // not your turn?
monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
}
print(i, "Even");
evensTurn = false; // next odd needs to run
monitor.notifyAll(); // wakeup the odd thread
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
public static class OddCallable implements Callable<Void> {
@Override
public Void call() throws InterruptedException {
for (int i = 1; i < 10; i++) {
if (i % 2 != 0) {
synchronized (monitor) {
while (evensTurn) {
monitor.wait();
}
print(i, "Odd");
evensTurn = true;
monitor.notifyAll();
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
}
TA贡献1864条经验 获得超2个赞
synchronized 用于锁定另一个线程的访问,当被锁定的对象空闲时,它不保证下一个调用哪个线程。您可以使用信号量进行线程间通信:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
TA贡献1805条经验 获得超10个赞
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
@Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}
添加回答
举报