Java 多线程 - 如何以自然顺序打印数字

Java Multithreading - How to print numbers in natural order

我在采访中了解到:

Thread-A Prints Even numbers from 0
Thread-B prints Odd numbers from 1

我想按自然顺序打印 0 1 2 3 4.... 直到 1000 我怎样才能达到。

我这样试过:

public class ThreadDemo2 {
    static int aa = 0;

    public static void main(String[] args) {
        boolean mytime = true;
        EvenThread et = new EvenThread(mytime);
        OddThread ot = new OddThread(mytime);
        et.start();
        ot.start();

    }

}

class EvenThread extends Thread {
    boolean mytime;
    int i = 0;

    public EvenThread(boolean mytime) {
        this.mytime = mytime;
    }

    public void run() {
        //if (ThreadDemo2.aa == 0) {
            for (int i = 0; i < 1000 && ThreadDemo2.aa == 0; i += 2) {
                System.out.println(i);
                ThreadDemo2.aa = 1;
                try {
                    sleep(500);

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        //  }

        }/* else
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
    }

}

class OddThread extends Thread {
    boolean mytime;
    int i = 1;

    public OddThread(boolean mytime) {
        this.mytime = mytime;
    }

    public void run() {
        //if (ThreadDemo2.aa == 1) {
            for (int i = 1; i < 1000 && ThreadDemo2.aa == 1; i += 2) {
                System.out.println(i);
                ThreadDemo2.aa = 0;
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //ThreadDemo2.aa = 0;
        //}
    }

}

当你启动线程时,那时,ThreadDemo2.aa = 0.

因此,OddThread 中的 for 循环永远不会启动。因此程序不会向前推进。

改为:

  • 从两个 for 循环中删除条件 && ThreadDemo2.aa == 0//or 1
  • 去掉时间延迟。
  • 在各自的循环中添加此行:while(ThreadDemo2.aa == 0){}// or 1

此行将使 for 循环等待,直到值正确,然后循环才继续前进。这应该可以解决您的问题。

不幸的是,由于 JVM 在 2 个不同的线程上工作,因此您无法期待结果,但您可以这样做,

public class Test12 {

public static void main(String[] args) {
    Thread1 t1=new Thread1();
    Thread2 t2=new Thread2();


}

}

class Thread1 implements Runnable {

public Thread1() {
    Thread t = new Thread();
    t.start();
}

@Override
public void run() {
    try {
        for (int i = 0; i < 1000; i++) {
            if (i % 2 == 0) {
                System.out.println(i);
            }

        }

    } catch (Exception e) {

    }
}
}

class Thread2 implements Runnable {

public Thread2() {
    Thread t = new Thread(this);
    t.start();

}

@Override
public void run() {
    try {
        for (int i = 0; i < 1000; i++) {
            if (i % 2 == 1) {
                System.out.println(i);
            }

        }

    } catch (Exception e) {

    }
}

}

当你多次运行这个应用程序时,你会发现没有像其他 100%

那样的结果

此方法可让您执行任务。使用监视器,您将不需要添加额外的循环来确保正确的输出。

public class ThreadDemo2 {
    static int aa = 0;
    static Object lock = new Object();

    public static void toggleThread(int threadaa) throws Exception
    {
    synchronized(lock)
    {
        if(aa == threadaa)
        {
            aa = (threadaa - 1) * -1;
            lock.notifyAll();
            lock.wait();
        }
        else
        {
            lock.wait();
        }
    }
    }

    public static void releaseThreads()
    {
    try
    {
            synchronized(lock)
        {
            lock.notifyAll();
        }
    }
    catch(Exception e)
    {
    }
    }

    public static void main(String[] args) {
        boolean mytime = true;
        EvenThread et = new EvenThread(mytime);
        OddThread ot = new OddThread(mytime);
        et.start();
        ot.start();

    }

}

class EvenThread extends Thread {
    boolean mytime;
    int i = 0;

    public EvenThread(boolean mytime) {
        this.mytime = mytime;
    }

    public void run() {
        //if (ThreadDemo2.aa == 0) {
            for (int i = 0; i < 10; i += 2) {       
                try {
                    ThreadDemo2.toggleThread(0);

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        System.out.println(i);
        //  }

        }/* else
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }*/
    ThreadDemo2.releaseThreads();
    }

}

class OddThread extends Thread {
    boolean mytime;
    int i = 1;

    public OddThread(boolean mytime) {
        this.mytime = mytime;
    }

    public void run() {
        //if (ThreadDemo2.aa == 1) {
            for (int i = 1; i < 10; i += 2) {


                try {
                    ThreadDemo2.toggleThread(1);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        System.out.println(i);
            }
            //ThreadDemo2.aa = 0;
        //}
    ThreadDemo2.releaseThreads();
    }

}

您练习的范围可能是使用线程锁。下面的例子使用了两个监控对象锁。每个线程基本上都在等待另一个线程完成其迭代,然后再继续前进。

public class ThreadInterleave {

    public static class Even implements Runnable{
        private Object even;
        private Object odd;
        private int count = 0;

        public Even(Object even,Object odd){
            this.even = even;
            this.odd = odd;
        }

        public void run(){
            while(count<1000) {
                    System.out.println(count);
                    count+=2;
                synchronized (odd){
                    odd.notify();
                }

                synchronized (even){
                    try {
                        even.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }



            }
        }
    }

    public static class Odd implements Runnable{
        private Object even;
        private Object odd;
        private int count = 1;

        public Odd(Object even,Object odd){
            this.even = even;
            this.odd = odd;
        }

        public void run(){
            while(count<1000) {
                System.out.println(count);
                count+=2;
                synchronized (even){
                    even.notify();
                }

                synchronized (odd){
                    try {
                        odd.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }



            }
        }
    }

public static void main(String[] args){
        final Object even = new Object();
        final Object odd = new Object();
        Thread tEven = new Thread(new Even(even,odd));
        Thread tOdd = new Thread(new Odd(even,odd));


        tEven.start();
        tOdd.start();



    }
}