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

时间:2016-03-23 12:14:55

标签: java multithreading thread-sleep thread-synchronization

我接受采访时说:

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;
        //}
    }

}

4 个答案:

答案 0 :(得分:0)

当您启动主题时,ThreadDemo2.aa = 0

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

相反:

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

此行将使for循环等待,直到值正确,然后只有循环向前移动。这应该可以解决你的问题。

答案 1 :(得分:0)

不幸的是,由于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%

的结果

答案 2 :(得分:0)

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

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

}

答案 3 :(得分:0)

你的练习范围可能是使用Thread锁。以下示例使用两个Monitor Object锁。每个线程基本上等待另一个线程在向前移动之前完成其迭代。

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



    }
}