我创建了两个可运行的作业:PrintEvenNumbersJob和PrintOddNumbersJob,并生成了两个线程来执行这些作业。这似乎工作得很好!但是我对此实施感到有些怀疑。我可以对此实施提出一些意见和建议吗?

我看到的这种实现的问题是,仅当线程1首先获得对对象锁的锁定时,程序才会终止,否则它将打印奇数第一个偶数二阶并且不会终止,除非我在之后提供另一个语句“ lock.notify”用于PrintEvenNumbersJob中的语句(如本实现中所示)。我的问题是如何确保先执行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();

}

}

最佳答案

您是否尝试过使用信号量?这样比较容易,因为您不必担心等待和通知的调用顺序(如果在等待之前调用通知,则“丢失”)

样例代码:

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();
    }

}

10-02 05:14