【问题标题】:Printing Even and Odd using two Threads in Java在 Java 中使用两个线程打印偶数和奇数
【发布时间】:2013-05-17 08:49:58
【问题描述】:

我尝试了下面的代码。我从其他一些帖子中获取了这段代码,根据作者的说法是正确的。但是当我尝试跑步时,它并没有给我确切的结果。

这主要是顺序打印偶数和奇数。

public class PrintEvenOddTester {



    public static void main(String ... args){
        Printer print = new Printer(false);
        Thread t1 = new Thread(new TaskEvenOdd(print));
        Thread t2 = new Thread(new TaskEvenOdd(print));
        t1.start();
        t2.start();
    }


}



class TaskEvenOdd implements Runnable {

    int number=1;
    Printer print;

    TaskEvenOdd(Printer print){
        this.print = print;
    }

    @Override
    public void run() {

        System.out.println("Run method");
        while(number<10){

            if(number%2 == 0){
                System.out.println("Number is :"+ number);
                print.printEven(number);
                number+=2;
            }
            else {
                System.out.println("Number is :"+ number);
                print.printOdd(number);
                number+=2;
            }
        }

      }

    }

class Printer {

    boolean isOdd;

    Printer(boolean isOdd){
        this.isOdd = isOdd;
    }

    synchronized void printEven(int number) {

        while(isOdd){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Even:"+number);
        isOdd = true;
        notifyAll();
    }

    synchronized void printOdd(int number) {
        while(!isOdd){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Odd:"+number);
        isOdd = false;
        notifyAll();
    }

}

有人可以帮我解决这个问题吗?

编辑 预期结果: 奇数:1 偶数:2 奇数:3 偶数:4 奇数:5 偶数:6 奇数:7 偶数:8 奇数:9

【问题讨论】:

  • 实际结果是什么,您的预期结果是什么?
  • 数字从 1 开始,你只能将它增加 2。因此它永远不会是偶数。
  • 这不是调试服务...
  • 对于每一位来到这里的学生:请告诉你的导师,虽然这个练习可能会教你一些关于如何控制线程的知识,但这是一个非常可怕的示例为什么 使用线程。如果您希望程序以特定顺序(例如,1、2、3,...)执行某些事情(例如,打印数字);那么绝对最好的方法就是在一个线程中完成这些事情。每个多线程程序都需要线程之间的一些同步,但是你使用的同步越多,你从线程中获得的好处就越少。这个程序实际上得到了负面的好处。
  • 没有理由让线程交替打印数字,甚至撇开关于增量的错误。您的期望是误入歧途的,未引用的“其他一些代码”也是如此。 SO 不是针对任意 Internet 垃圾的验证服务。

标签: java multithreading synchronization


【解决方案1】:

此解决方案适用于我(Java 8 及更高版本使用 Lamda 表达式)

public class EvenOddUsingThread {

    static int number = 100;
    static int counter = 1;

    public static void main(String[] args) {
        EvenOddUsingThread eod = new EvenOddUsingThread();
        Thread t1 = new Thread(() -> eod.printOdd());
        Thread t2 = new Thread(() -> eod.printEven());
        t1.start();
        t2.start();
    }

    public void printOdd() {
        synchronized (this) {
            while (counter < number) {
                if (counter % 2 == 0) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
                // Print the number
                System.out.println(counter + " Thread Name: " + Thread.currentThread().getName());
                // Increment counter
                counter++;
                // Notify to second thread
                notify();
            }
        }
    }

    public void printEven() {
        synchronized (this) {
            while (counter < number) {
                if (counter % 2 == 1) {
                    try {
                        wait();
                    } catch (InterruptedException ignored) {
                    }
                }
                // Print the number
                System.out.println(counter + " Thread Name: " + Thread.currentThread().getName());
                // Increment counter
                counter++;
                // Notify to second thread
                notify();
            }
        }
    }

}

【讨论】:

    【解决方案2】:

    下面的解决方案是使用 java 8 可完成的 future 和 executor 服务使用两个线程打印偶数和奇数。

    ExecutorService firstExecutorService = Executors.newSingleThreadExecutor(r -> {
            Thread t = new Thread(r);
            t.setName("first");
            return t;
        });
    
        ExecutorService secondExecutorService = Executors.newSingleThreadExecutor(r -> {
            Thread t = new Thread(r);
            t.setName("second");
            return t;
        });
    
        IntStream.range(1, 101).forEach(num -> {
    
            CompletableFuture<Integer> thenApplyAsync = CompletableFuture.completedFuture(num).thenApplyAsync(x -> {
    
                if (x % 2 == 1) {
                    System.out.println(x + " " + Thread.currentThread().getName());
                }
                return num;
            }, firstExecutorService);
    
            thenApplyAsync.join();
    
            CompletableFuture<Integer> thenApplyAsync2 = CompletableFuture.completedFuture(num).thenApplyAsync(x -> {
                if (x % 2 == 0) {
                    System.out.println(x + " " + Thread.currentThread().getName());
                }
                return num;
            }, secondExecutorService);
    
            thenApplyAsync2.join();
        });
    
        firstExecutorService.shutdown();
        secondExecutorService.shutdown();
    

    下面是它的控制台日志。

    【讨论】:

      【解决方案3】:

      公共类 EvenOddex {

      public static class print {
      
          int n;
          boolean isOdd = false;
      
          synchronized public void printEven(int n) {
      
              while (isOdd) {
                  try {
                      wait();
                  } catch (InterruptedException ex) {
                      Logger.getLogger(EvenOddex.class.getName()).log(Level.SEVERE, null, ex);
                  }
      
              }
      
              System.out.print(Thread.currentThread().getName() + n + "\n");
      
              isOdd = true;
              notify();
          }
      
          synchronized public void printOdd(int n) {
              while (!isOdd) {
                  try {
                      wait();
                  } catch (InterruptedException ex) {
                      Logger.getLogger(EvenOddex.class.getName()).log(Level.SEVERE, null, ex);
                  }
              }
      
      
              System.out.print(Thread.currentThread().getName() + n + "\n");
              isOdd = false;
              notify();
      
      
      
          }
      }
      
      public static class even extends Thread {
      
          print po;
      
          even(print po) {
      
              this.po = po;
      
              new Thread(this, "Even").start();
      
          }
      
          @Override
          public void run() {
      
      
              for (int j = 0; j < 10; j++) {
                  if ((j % 2) == 0) {
                      po.printEven(j);
                  }
              }
      
          }
      }
      
      public static class odd extends Thread {
      
          print po;
      
          odd(print po) {
      
              this.po = po;
              new Thread(this, "Odd").start();
          }
      
          @Override
          public void run() {
      
              for (int i = 0; i < 10; i++) {
      
                  if ((i % 2) != 0) {
                      po.printOdd(i);
                  }
              }
      
          }
      }
      
      public static void main(String args[]) {
          print po = new print();
          new even(po);
          new odd(po);
      
      }
      

      }

      【讨论】:

        【解决方案4】:
        public class Multi extends Thread{  
            public static int a;
            static{a=1;}
            public void run(){  
                for(int i=1;i<5;i++){  
                System.out.println("Thread Id  "+this.getId()+"  Value "+a++);
                try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}  
        
                }  
            }  
        public static void main(String args[]){  
               Multi t1=new Multi();  
               Multi t2=new Multi();  
        
              t1.start();  
              t2.start();  
            }  
        }  
        

        【讨论】:

        • 程序的正确性取决于'Thread.sleep();'你在那里写的。它会产生不可预知的结果。我们的想法是创建一个可以确定地产生预期结果的程序。
        【解决方案5】:
        public class PrintOddEven {
        private static class PrinterThread extends Thread {
        
            private static int current = 0;
            private static final Object LOCK = new Object();
        
            private PrinterThread(String name, int number) {
                this.name = name;
                this.number = number;
            }
        
            @Override
            public void run() {
                while (true) {
                    synchronized (LOCK) {
                        try {
                            LOCK.wait(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
        
                        if (current < number) {
                            System.out.println(name + ++current);
                        } else {
                            break;
                        }
        
                        LOCK.notifyAll();
                    }
                }
            }
        
            int number;
            String name;
        }
        
        public static void main(String[] args) {
            new PrinterThread("thread1 : ", 20).start();
            new PrinterThread("thread2 : ", 20).start();
        }
        }
        

        【讨论】:

          【解决方案6】:

          公共类解决方案{

           static class NumberGenerator{
          
               private static volatile boolean printEvenNumber = false;
          
          
               public  void printEvenNumber(int i) {
                   synchronized (this) {
                       if(!printEvenNumber) {
                           try {
                               wait();
                           } catch (InterruptedException e) {
                               e.printStackTrace();
                           }
                       }
                       System.out.println(i);
                       printEvenNumber = !printEvenNumber;
                       notify();
                   }
               }
          
               public  void printOddNumber(int i ) {
                      synchronized (this) {
                          if(printEvenNumber) {
                              try {
                                  wait();
                              } catch (InterruptedException e) {
                                  e.printStackTrace();
                              }
                          }
          
                          System.out.println(i);
                          printEvenNumber = !printEvenNumber;
                          notify();
                      }
               }
          
          }
          
          static  class OddNumberGenerator implements Runnable{
              private NumberGenerator numberGenerator;
          
              public OddNumberGenerator(NumberGenerator numberGenerator) {
                  this.numberGenerator = numberGenerator;
              }
          
              @Override
              public void run() {
                  for(int i  = 1; i <100; i = i + 2) {
                      numberGenerator.printOddNumber(i);
                  }
              }
          }
          
          static class EvenNumberGenerator implements Runnable {
              private NumberGenerator numberGenerator;
          
              public EvenNumberGenerator(NumberGenerator numberGenerator) {
                  this.numberGenerator = numberGenerator;
              }
          
              @Override
              public void run() {
                  for (int i = 2; i <= 100; i =  i + 2) {
                     numberGenerator.printEvenNumber(i);
                  }
              }
          }
          
          
          public static void main(String[] args) {
              NumberGenerator ng = new NumberGenerator();
              OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(ng);
              EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(ng);
              new Thread(oddNumberGenerator).start();
              new Thread(evenNumberGenerator).start();
          
          }
          

          }

          【讨论】:

            【解决方案7】:
            package programs.multithreading;
            
            public class PrintOddEvenNoInSequence {
            
            final int upto;
            final PrintOddEvenNoInSequence obj;
            volatile boolean oddFlag,evenFlag;
            public PrintOddEvenNoInSequence(int upto){
                this.upto = upto;
                obj = this;
                oddFlag = true;
                evenFlag = false;
            }
            void printInSequence(){
            
                Thread odd = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for(int i = 1; i <= upto; i = i + 2){
                            synchronized (obj) {
                                while(!oddFlag){
                                    try {
                                        obj.wait();
                                    } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                }
                                System.out.println("Odd:"+i);
                                oddFlag = false;
                                evenFlag = true;
                                obj.notify();
                            }
                        }
                    }
                });
            
                Thread even = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for(int i = 2; i <= upto; i = i + 2){
                            synchronized (obj) {
                                while(!evenFlag){
                                    try {
                                        obj.wait();
                                    } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                }
                                System.out.println("Even:"+i);
                                oddFlag = true;
                                evenFlag = false;
                                obj.notify();
                            }
                        }
                    }
                });
            
                odd.start();
                even.start();
            
            }
            public static void main(String[] args) {
                new PrintOddEvenNoInSequence(100).printInSequence();
            }
            }
            

            【讨论】:

            • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
            【解决方案8】:

            查看 Clean 实现

            public class PrintOddEvenByTwoThreads {
                static int number = 1;
                static Thread odd;
                static Thread even;
                static int max = 10;
            
                static class OddThread extends Thread {
                    @Override
                    public void run() {
                        while (number <= max) {
                            if (number % 2 == 1) {
                                System.out.println(Thread.currentThread() + "" + number++);
                            } else {
            
                                synchronized (odd) {
                                    synchronized (even) {
                                        even.notify();
                                    }
                                    try {
                                        wait();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            
                static class EvenThread extends Thread {
                    @Override
                    public void run() {
                        while (number <= max) {
                            if (number % 2 == 0) {
                                System.out.println(Thread.currentThread() + "" + number++);
                            } else {
            
                                synchronized (even) {
                                    synchronized (odd) {
                                        odd.notify();
                                    }
                                    try {
                                        wait();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        }
                    }
                }
            
                public static void main(String[] args) throws InterruptedException {
                    odd = new OddThread();
                    even = new EvenThread();
                    odd.start();
                    even.start();
                }
            }
            

            【讨论】:

              【解决方案9】:

              1- 数字初始化为 1,isOdd 标志设置为 false。将isOdd 设置为 true

              2- 增量应为 1(而不是 2),即 number+=1

              【讨论】:

                【解决方案10】:
                import java.util.concurrent.Semaphore;
                
                
                public class PrintOddAndEven {
                
                private static class OddThread extends Thread {
                    private Semaphore semaphore;
                    private Semaphore otherSemaphore;
                    private int value = 1;
                
                    public  OddThread(Semaphore semaphore, Semaphore otherSemaphore) {
                        this.semaphore = semaphore;
                        this.otherSemaphore = otherSemaphore;
                    }
                
                    public void run() {
                        while (value <= 100) {
                            try {
                                // Acquire odd semaphore
                                semaphore.acquire();
                                System.out.println(" Odd Thread " + value + " " + Thread.currentThread().getName());
                
                            } catch (InterruptedException excetion) {
                                excetion.printStackTrace();
                            }
                            value = value + 2;
                            // Release odd semaphore
                            otherSemaphore.release();
                        }
                    }
                }
                
                
                private static class EvenThread extends Thread {
                    private Semaphore semaphore;
                    private Semaphore otherSemaphore;
                
                    private int value = 2;
                
                    public  EvenThread(Semaphore semaphore, Semaphore otherSemaphore) {
                        this.semaphore = semaphore;
                        this.otherSemaphore = otherSemaphore;
                    }
                
                    public void run() {
                        while (value <= 100) {
                            try {
                                // Acquire even semaphore
                                semaphore.acquire();
                                System.out.println(" Even Thread " + value + " " + Thread.currentThread().getName());
                
                            } catch (InterruptedException excetion) {
                                excetion.printStackTrace();
                            }
                            value = value + 2;
                            // Release odd semaphore
                            otherSemaphore.release();
                        }
                    }
                }
                
                
                public static void main(String[] args) {
                    //Initialize oddSemaphore with permit 1
                    Semaphore oddSemaphore = new Semaphore(1);
                    //Initialize evenSempahore with permit 0
                    Semaphore evenSempahore = new Semaphore(0);
                    OddThread oddThread = new OddThread(oddSemaphore, evenSempahore);
                    EvenThread evenThread = new EvenThread(evenSempahore, oddSemaphore);
                    oddThread.start();
                    evenThread.start();
                    }
                }
                

                【讨论】:

                • 在代码中添加了 cmets。程序打印 1 到 100,在两个线程之间共享。
                【解决方案11】:

                下面的简单解决方案:-

                package com.test;
                
                class MyThread implements Runnable{
                
                    @Override
                    public void run() {
                        int i=1;
                        while(true) {
                            String name=Thread.currentThread().getName();
                            if(name.equals("task1") && i%2!=0) {
                                System.out.println(name+"::::"+i);
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }else if(name.equals("task2") && i%2==0){
                                System.out.println(name+"::::"+i);
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            i++;
                        }
                
                    }
                
                    public static void main(String[] args) {
                
                        MyThread task1=new MyThread();
                        MyThread task2=new MyThread();
                
                        Thread t1=new Thread(task1,"task1");
                        Thread t2=new Thread(task2,"task2");
                
                        t1.start();
                        t2.start();
                
                    }
                
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-03-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-08-26
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多