Java 使用wait/notify的顺序线程执行

Java 使用wait/notify的顺序线程执行,java,multithreading,java-threads,Java,Multithreading,Java Threads,现在我正在努力完成标题中的任务。我创建X个线程,每个线程在循环中打印Z次的Y个相等数字(从构造函数获取,例如“11111”、“222222”等)。因此,结果如下所示: 111111111 222222222 333333333 111111111 222222222 333333333 对于X=3,Y=9,Z=2。 首先,我使用睡眠、中断和将“下一个”线程传递给前一个线程的构造函数来解决这个问题。一个中断另一个等。下一步是使用wait/notify而不是sleep和interrupt获得相同的

现在我正在努力完成标题中的任务。我创建X个线程,每个线程在循环中打印Z次的Y个相等数字(从构造函数获取,例如“11111”、“222222”等)。因此,结果如下所示:

111111111
222222222
333333333
111111111
222222222
333333333
对于X=3,Y=9,Z=2。 首先,我使用睡眠、中断和将“下一个”线程传递给前一个线程的构造函数来解决这个问题。一个中断另一个等。下一步是使用wait/notify而不是sleep和interrupt获得相同的输出。就我所见,有必要创建共享监视器对象,在每次打印之后调用wait,并在某个时刻“我应该调用notifyAll”。 目前的代码是:

public class PrinterController {

    private static final int THREADS_NUMBER = 5;

    public static void main(String[] args) {

        Printer[] printers = new Printer[THREADS_NUMBER];
        for (int i = 0; i < THREADS_NUMBER; i++) {
            printers[i] = new Printer(i);
            printers[i].start();
        }
    }
}   

public class Printer extends Thread {

    private static int portion = 10;
    private static int totalNumber = 100;
    private int digit;
    private static final Object monitor = new Object();

    public Printer(int digit) {
        this.digit = digit;
    }

    @Override
    public void run() {
        synchronized (monitor) {
            int portionsNumber = totalNumber / portion;
            for (int i = 0; i < portionsNumber; i++) {
                printLine();
                try {
                    monitor.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void printLine() {
        for (int j = 0; j < portion; j++) {
            System.out.print(digit);
        }
        System.out.println();
    }

}
公共类PrinterController{
私有静态最终整数线程数=5;
公共静态void main(字符串[]args){
打印机[]打印机=新打印机[线程数];
对于(int i=0;i
你能帮我改进一下吗?我发现了类似的任务,但没有合适的答案。谢谢


基于最低点答案的最终解决方案:

public class Printer extends Thread {

    private static int portion = 10;
    private static int totalNumber = 100;
    private int digit;
    static Object monitor = new Object();
    static Integer counter = 0;

    public Printer(int digit) {
        this.digit = digit;
    }

    @Override
    public void run() {
        int portionsNumber = totalNumber / portion;
        for (int i = 0; i < portionsNumber; i++) {
            synchronized (monitor) {
                while (digit != counter) {
                    try {
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                printLine();
                monitor.notifyAll();
            }
        }
    }

    private void printLine() {
        for (int j = 0; j < portion; j++) {
            System.out.print(digit);
        }
        System.out.println();
        counter = (counter + 1) % PrinterController.THREADS_NUMBER;
    }
}
公共类打印机扩展线程{
专用静态int部分=10;
私有静态整数totalNumber=100;
专用整数位数;
静态对象监视器=新对象();
静态整数计数器=0;
公用打印机(整数位){
this.digit=数字;
}
@凌驾
公开募捐{
int PORTIONSNOUMBER=总数/部分;
for(int i=0;i
可以通过一个用于同步线程(甚至确保它们是订购者)的类来完成。所有线程将共享同一个实例

public class Synchronizer 
{
    private int nextThread;
    private int maxNumThreads;

    public Synchronizer(int numThreads)
    {
        maxNumThreads = numThreads;
        nextThread = 0;
    }

    public void doSync(int threadId) throws Exception
    {
        synchronized(this)
        {
            while(nextThread != threadId)
            {
                wait();
            }
        }
    }

    public void threadDone(int threadId) throws Exception
    {
        synchronized(this)
        {
            nextThread = (threadId + 1) % maxNumThreads;
            notifyAll();
        }
    }
}

在线程的
run()
上,在打印任何内容之前调用
doSync()
。然后放入要打印的代码,然后调用
threadDone()
,允许释放下一个线程。id用于强制执行订单。

它可以通过用于同步线程(甚至确保它们是订购者)的类来完成。所有线程将共享同一个实例

public class Synchronizer 
{
    private int nextThread;
    private int maxNumThreads;

    public Synchronizer(int numThreads)
    {
        maxNumThreads = numThreads;
        nextThread = 0;
    }

    public void doSync(int threadId) throws Exception
    {
        synchronized(this)
        {
            while(nextThread != threadId)
            {
                wait();
            }
        }
    }

    public void threadDone(int threadId) throws Exception
    {
        synchronized(this)
        {
            nextThread = (threadId + 1) % maxNumThreads;
            notifyAll();
        }
    }
}

在线程的
run()
上,在打印任何内容之前调用
doSync()
。然后放入要打印的代码,然后调用
threadDone()
,允许释放下一个线程。id用于强制执行命令。

使用
CyclicBarrier
Phaser
。使用
wait
/
notify
是练习的要求,还是允许使用
信号灯等实用程序?是的,只需等待/通知。使用
CyclicBarrier
相位器
。练习要求您使用
等待
/
通知
,还是允许您使用
信号灯等实用程序
?是的,只需等待/通知即可。