【问题标题】:Java Multithreading - How to print numbers in natural order [duplicate]Java多线程-如何以自然顺序打印数字[重复]
【发布时间】:2016-03-23 12:14:54
【问题描述】:

我得到了采访:

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

}

【问题讨论】:

  • 不要指望别人复制你的代码,编译并运行它。如果你告诉我们会发生什么事情会更容易。此外,据我所知,您的代码缺少此处所需的基本内容:您必须互锁两个线程,基本上它们需要同步运行才能以正确的顺序打印数字。这就像作业的 hard 部分。那么,您希望我们为您完成繁重的工作吗?
  • @Jägermeister,这与我们通常告诉人们的相反。您希望 OP “告诉您发生了什么”,但 OP 不了解会发生什么。这就是他问的原因。没有比代码本身更好地描述代码实际执行的操作了。试着数一下 SO 上的 cmets,上面写着“老兄!给我们看看你的代码!” OTOH,有时他们发布了太多代码,我们要求他们简化它:(见sscce.org
  • 请参阅:stackoverflow.com/a/36183057/437506 以获取其他信息。

标签: java multithreading thread-sleep thread-synchronization


【解决方案1】:

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

【讨论】:

  • 谢谢,它可以工作,我能够理解代码。但如果我将 1000 更改为 10,它将无法正常工作。
  • 我告诉过你你不能期待结果所以没有像其他 100% 那样的结果它取决于操作系统或你的 JVM 我不确定
【解决方案2】:

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

所以,OddThread 中的 for 循环永远不会启动。因此程序没有前进。

改为:

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

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

【讨论】:

  • 变量 aa 也必须声明为 volatile,否则其他线程永远无法看到所做的更改。
  • @Leto,也许你是对的,但我尝试了这些更改,并且效果很好,没有声明 aa volatile。
【解决方案3】:

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

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

}

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多