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();
}
}
添加回答
舉報