Java 使用多线程顺序打印数字

Java 使用多线程顺序打印数字,java,multithreading,sequence,Java,Multithreading,Sequence,我试图创建多个线程,一个接一个地按顺序打印数字 我试着给每个线程分配一个值,并且只在 计数器%no of threads==该线程的值,否则线程将等待 当我用2个线程尝试这个方法时,我能够获得结果,但是程序在3个线程中没有正确运行 import java.util.*; import java.lang.*; class Ideone { public static void main (String[] args) throws java.lang.Exception {

我试图创建多个线程,一个接一个地按顺序打印数字

我试着给每个线程分配一个值,并且只在

计数器%no of threads==该线程的值,否则线程将等待

当我用2个线程尝试这个方法时,我能够获得结果,但是程序在3个线程中没有正确运行

import java.util.*;
import java.lang.*;
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        printer p1 = new printer(l,0);
        printer p2 = new printer(l,1);
        printer p3 = new printer(l,2);
        Thread t1 = new Thread(p1);
        Thread t2 = new Thread(p2);
        Thread t3 = new Thread(p3);
        t1.start();
        t2.start();
        t3.start();
    }
    static Object l = new Object();
    static int c = 0;
}
class printer implements Runnable{
    Object lock;
    static int i = 0;
    int j;
    printer(Object lock,int j){
        this.lock = lock;
        this.j=j;
    }
    public void run(){

        synchronized(lock){
            try{
                while(i<1000){
                        System.out.println(Thread.currentThread().getName()+" starting to check with j="+j+ " i="+i);

                        if(i%3!=j){
                            System.out.println(Thread.currentThread().getName()+" not the one so waiting");
                            lock.wait();
                        }

                        System.out.println(Thread.currentThread().getName()+" i="+i);
                        i++;

                        lock.notifyAll();

                }

            }catch(InterruptedException ex ){

            }


        }


    }
}
我不明白的是,线程0 I=2是如何在没有经过检查的情况下由线程0打印出来的。线程0没有检查其值的打印语句 我本来希望线程2从这里开始,但是线程0开始运行。此外,Thread-0也没有执行任何检查,而是直接打印i的值

我的目标是理解为什么这不能按预期工作,以及为什么代码会以这种方式运行


请不要向我提供实现所需结果的其他代码片段。

我认为会发生以下情况:

某些线程启动后发现它不是该线程,因此等待:

if(i%3!=j){
  System.out.println(Thread.currentThread().getName()+" not the one so waiting");
  lock.wait();
}
然后另一个线程找到它,打印并递增,然后通知所有线程。那么上面的线程是做什么的呢?它只是一直在执行

if(i%3!=j){
  System.out.println(Thread.currentThread().getName()+" not the one so waiting");
  lock.wait();
}
// just keeps going...
System.out.println(Thread.currentThread().getName()+" i="+i);
i++;
程序按顺序执行。在一次检查之后,您的程序唯一能做的就是转到下一个print语句。代码没有其他功能

检查和等待的标准方法是使用while循环,以便在检查成功之前不会退出while

while(i%3!=j){
  System.out.println(Thread.currentThread().getName()+" not the one so waiting");
  lock.wait();
}

没有测试,试一试。

这是一个非常糟糕的例子,除了学术练习之外。通常,您希望以异步方式尽可能快地运行线程,这意味着需要按特定顺序执行的小步骤的问题不适合多线程解决方案。作为一个线程,这可能会运行得更快。没错,我并不是想通过这个程序实现任何现实生活中的目标,而是想帮助我理解为什么它会以这种方式运行。这很好,学术练习是一种很好的学习方式。我只是想指出,在现实生活中,你必须认真考虑如何实现像这样的多线程。非常感谢,使用while循环确实解决了这个问题。所以问题是因为没有持续检查线程是否是打印值的线程。
while(i%3!=j){
  System.out.println(Thread.currentThread().getName()+" not the one so waiting");
  lock.wait();
}