22

我正在尝试创建两个线程,一个线程显示0到10的偶数,一个线程显示1到11的奇数。下面的代码适合设计这个程序吗?

public class Mythread {

    public static void main(String[] args) {
        Runnable r = new Runnable1();
        Thread t = new Thread(r);
        t.start();
        Runnable r2 = new Runnable2();
        Thread t2 = new Thread(r2);
        t2.start();
    }
}

class Runnable2 implements Runnable{
    public void run(){
        for(int i=0;i<11;i++){
            if(i%2 == 1)
                System.out.println(i);
        }
    }
}

class Runnable1 implements Runnable{
    public void run(){
        for(int i=0;i<11;i++){
            if(i%2 == 0)
                System.out.println(i);
        }
    }
}
4

21 回答 21

45

@aymeric 答案不会按自然顺序打印数字,但这段代码会。解释在最后。

public class Driver {
    static Object lock = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            public void run() {

                for (int itr = 1; itr < 51; itr = itr + 2) {
                    synchronized (lock) {
                        System.out.print(" " + itr);
                        try {
                            lock.notify();
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            public void run() {

                for (int itr = 2; itr < 51; itr = itr + 2) {
                    synchronized (lock) {
                        System.out.print(" " + itr);
                        try {
                            lock.notify();
                            if(itr==50)
                                break;
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        try {
            t1.start();
            t2.start();
            t1.join();
            t2.join();
            System.out.println("\nPrinting over");
        } catch (Exception e) {

        }
    }
}

为了实现这一点,上面两个线程的运行方法必须一个接一个地调用,即它们需要同步,我正在使用锁来实现。

代码的工作方式如下: t1.run 打印奇数并通知任何等待线程它将释放锁,然后进入等待状态。

此时 t2.run 被调用,它打印下一个偶数,通知其他线程它即将释放它持有的锁,然后进入等待状态。

这一直持续到 t2.run() 中的 itr 达到 50,此时我们的目标已经实现,我们需要杀死这两个线程。

通过中断,我避免在 t2.run 中调用 lock.wait() 并且因此关闭了 t2 线程,控制现在将转到 t1.run,因为它正在等待获取锁;但是这里它的值将> 51,我们将退出它的run(),从而关闭线程。

如果在 t2.run() 中没有使用 break,虽然我们会在屏幕上看到数字 1 到 50,但两个线程会陷入死锁情况并继续处于等待状态。

于 2015-06-12T17:32:31.993 回答
15

我只想更改一些细节(此处无需使用模运算符...):

public class Mythread {

    public static void main(String[] args) {
        Runnable r = new Runnable1();
        Thread t = new Thread(r);
        Runnable r2 = new Runnable2();
        Thread t2 = new Thread(r2);
        t.start();
        t2.start();
    }
}

class Runnable2 implements Runnable{
    public void run(){
        for(int i=0;i<11;i+=2) {
            System.out.println(i);
        }
    }
}

class Runnable1 implements Runnable{
    public void run(){
        for(int i=1;i<=11;i+=2) {
           System.out.println(i);
        }
    }
}
于 2012-12-09T09:19:28.130 回答
4

是的,很好。但是在这种情况下,我认为你不需要2个线程,因为操作很简单。但是,如果您正在练习线程,则可以

于 2012-12-09T09:29:32.937 回答
3

下面是在共享对象上使用锁定的代码,该共享对象具有要打印的数字。与上述解决方案不同,它也保证了顺序。

public class MultiThreadPrintNumber {
  int i = 1;

  public synchronized void printNumber(String threadNm) throws InterruptedException{

      if(threadNm.equals("t1")){
        if(i%2 == 1){
          System.out.println(Thread.currentThread().getName()+"--"+ i++);
          notify();
        } else {
          wait();
        }
      } else if(threadNm.equals("t2")){
        if(i%2 == 0){
          System.out.println(Thread.currentThread().getName()+"--"+ i++);
          notify();
        } else {
          wait();
        }
      }
      
    }

  public static void main(String[] args) {
    final MultiThreadPrintNumber obj = new MultiThreadPrintNumber();
    Thread t1 = new Thread(new Runnable() {

      @Override
      public void run() {
        try {
          while(obj.i <= 10){
            
            obj.printNumber(Thread.currentThread().getName());
          }
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println("done t1");
      }
    });
    Thread t2 = new Thread(new Runnable() {

      @Override
      public void run() {
        try {
          while(obj.i <=10){
            obj.printNumber(Thread.currentThread().getName());
          }
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println("done t2");
      }
    });

    t1.setName("t1");
    t2.setName("t2");
    t1.start();
    t2.start();
  }
}

输出将如下所示:

t1--1
t2--2
t1--3
t2--4
t1--5
t2--6
t1--7
t2--8
t1--9
t2--10
done t2
done t1
于 2015-08-07T15:45:44.247 回答
3
package javaapplication45;

public class JavaApplication45 extends Thread {

    public static void main(String[] args) {
        //even numbers
        Thread t1 = new Thread() {
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    if (i % 2 == 0) {
                        System.out.println("even thread " + i);
                    }
                }
            }
        };
        t1.start();
        //odd numbers
        Thread t2 = new Thread() {
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    if (i % 2 != 0) {
                        System.out.println("odd thread " + i);
                    }
                }
            }
        };
        t2.start();

    }

}
于 2016-04-18T15:58:59.403 回答
1

如果您需要其他选择,我也会考虑使用Java Concurrency 。Java Concurrency 包中提供的一些功能提供了更高级别的抽象,然后直接使用 Thread 类并因此提供更多功能。

对于您的具体情况,您所做的事情是相当合理的,但是这些数字的打印顺序重要吗?你想要赔率之前的偶数吗?这类问题将更好地表明最适合您需求的设计。

于 2012-12-09T09:22:27.353 回答
1
package thread;

import org.hibernate.annotations.Synchronize;

class PrintOdd implements Runnable {
    int count = -1;
    private Object common;

    PrintOdd(Object common) {
        this.common = common;
    }

    @Override
    public void run() {
        synchronized (common) {
            while (count < 1000) {
                try {
                    common.notifyAll();
                    System.out.println(count += 2);
                    common.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}

class PrintEven implements Runnable {

    int count = 0;
    private Object common;

    PrintEven(Object common) {
        this.common = common;
    }

    @Override
    public void run() {
        synchronized (common) {
            while (count < 1000) {
                try {
                    common.notifyAll();
                    System.out.println(count += 2);
                    common.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}

public class PrintNatural {
    public static void main(String args[]) {
        Object obj = new Object();
        Runnable r = new PrintOdd(obj);
        Thread printOdd = new Thread(r);

        Runnable r2 = new PrintEven(obj);
        Thread printEven = new Thread(r2);

        printOdd.start();
        printEven.start();

    }

}
于 2015-05-17T02:27:44.370 回答
1

编号将按顺序打印

Main class
===========
package com.thread;

import java.util.concurrent.atomic.AtomicInteger;

public class StartThread {
    static AtomicInteger no = new AtomicInteger(1);
    public static void main(String[] args) {
        Odd oddObj = new Odd();
        Thread odd = new Thread(oddObj);
        Thread even = new Thread(new Even(oddObj));
        odd.start();
        even.start();
    }
}

Odd Thread
===========
package com.thread;

public class Odd implements Runnable {

    @Override
    public void run() {
        while (StartThread.no.get() < 20) {
            synchronized (this) {
                System.out.println("Odd=>" + StartThread.no.get());
                StartThread.no.incrementAndGet();

                try {
                    this.notify();
                    if(StartThread.no.get() == 20)
                        break;
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

Even Thread
===========
package com.thread;

public class Even implements Runnable {
    Odd odd;

    public Even(Odd odd) {
        this.odd = odd;
    }

    @Override
    public void run() {
        while (StartThread.no.get() < 20) {
            synchronized (odd) {
                System.out.println("Even=>" + StartThread.no.get());
                StartThread.no.incrementAndGet();
                odd.notifyAll();
                try {
                    odd.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }       

    }

}

Output (Nos are printed in sequential)
======
Odd=>1
Even=>2
Odd=>3
Even=>4
Odd=>5
Even=>6
Odd=>7
Even=>8
Odd=>9
Even=>10
Odd=>11
Even=>12
Odd=>13
Even=>14
Odd=>15
Even=>16
Odd=>17
Even=>18
Odd=>19
于 2018-08-28T12:36:53.287 回答
1

并发套餐:

    import java.util.concurrent.ExecutorService;

    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    //=========== Task1 class prints odd =====
    class TaskClass1 implements Runnable
    {

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    int i;
    TaskClass1(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        try
        {
            lock.lock();
            for(i = 1;i<11;i++)
            {
                if(i%2 == 0)
                {
                    condition.signal();
                    condition.await();

                }
                if(i%2 != 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally
        {
            lock.unlock();
        }

    }

}
//==== Task2 : prints even =======
class TaskClass2 implements Runnable
{

    private Condition condition;
    private Lock lock;
    boolean exit = false;
    TaskClass2(Condition condition,Lock lock)
    {
        this.condition = condition;
        this.lock = lock;
    }
    @Override
    public void run() {
        int i;
        // TODO Auto-generated method stub
        try
        {
            lock.lock();
            for(i = 2;i<11;i++)

            {

                if(i%2 != 0)
                {
                    condition.signal();
                    condition.await();
                }
                if(i%2 == 0)
                {
                    System.out.println(Thread.currentThread().getName()+" == "+i);

                }

            }

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

        }

    }

}
public class OddEven {

    public static void main(String[] a)
    {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Future future1;
        Future future2;
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        future1 = executorService.submit(new TaskClass1(condition,lock));
        future2 = executorService.submit(new TaskClass2(condition,lock));
        executorService.shutdown();


    }


}
于 2016-03-20T08:35:21.330 回答
1

不是上述问题的答案,而是类似的问题。

程序按顺序打印数组的元素,但使用两个不同的线程打印相邻元素

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author ntv
 */
public class PrintLAternateNumber {
    public static void main(String[] args) {
        int [] num = {1,2,3,4,5,6};
        Printer p = new Printer();
        Thread t1 = new Thread(new Thread1(num,  p), "Thread1");
        Thread t2 = new Thread(new Thread2(num,  p), "Thread2");
        t1.start();
        t2.start();
    }


}

class Thread1 implements Runnable {
    int [] num;
    Printer p ;
    public Thread1(int[] num,  Printer p) {
        this.num = num;
        this.p = p;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            Logger.getLogger(Thread1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void print() throws InterruptedException {
        int i = 1;

            while(i < num.length) {
                synchronized(num) {
                    while (p.evenPrinted) {
                        num.wait();
                     }
                }   

                synchronized(num) {
                     p.printEven(Thread.currentThread().getName(), num[i]);
                     i= i + 2;
                     num.notifyAll();

                }
            }
    }
}


class Thread2 implements Runnable {
    int [] num;
    Printer p ;
    public Thread2(int[] num, Printer p) {
        this.num = num;
        this.p = p;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            Logger.getLogger(Thread2.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void print() throws InterruptedException {
        int i = 0;

            while(i < num.length) {
                synchronized(num) {
                    while (!p.evenPrinted) {
                        num.wait();
                     }
                }    

                 synchronized(num) {
                     p.printOdd(Thread.currentThread().getName(), num[i]);
                     i = i + 2;
                     num.notifyAll();

                }
            }
    }
}

class Printer {
    boolean evenPrinted = true;
    void printEven(String threadName , int i) {
        System.out.println(threadName + "," + i);
        evenPrinted = true;
    }


        void printOdd(String threadName , int i) {
        System.out.println(threadName + "," + i);
        evenPrinted = false;
    }
}
于 2016-10-18T08:45:47.820 回答
0
 public class ThreadClass {
   volatile int i = 1;
    volatile boolean state=true;

    synchronized public void printOddNumbers(){

                   try {
                       while (!state) {

                           wait();
                       }

                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                System.out.println(Thread.currentThread().getName()+" "+i);
                      state = false;
                      i++;
                      notifyAll();

    }

  synchronized  public void printEvenNumbers(){

      try {
          while (state) {

              wait();
          }

      } catch (InterruptedException e) {
          e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName()+" "+i);
      state = true;
      i++;
      notifyAll();

    }
}

然后像这样调用上面的类

   // I am ttying to print 10 values.
  ThreadClass threadClass=new ThreadClass();

        Thread t1=new Thread(){
            int k=0;
            @Override
            public void run() {
                while (k<5) {
                    threadClass.printOddNumbers();
                    k++;
                }
            }
        };
        t1.setName("Thread1");
        Thread t2=new Thread(){
            int j=0;
            @Override
            public void run() {
                while (j<5) {
                    threadClass.printEvenNumbers();
                    j++;
                }
            }
        };
        t2.setName("Thread2");

        t1.start();

        t2.start();
  1. 在这里,我试图打印 1 到 10 的数字。
  2. 一个线程试图打印偶数和另一个线程奇数。
  3. 我的逻辑是在奇数之后打印偶数。对于这个偶数线程应该等到奇数方法发出通知。
  4. 每个线程调用特定方法 5 次,因为我只尝试打印 10 个值。

输出:

System.out: Thread1 1
System.out: Thread2 2
System.out: Thread1 3
System.out: Thread2 4
System.out: Thread1 5
System.out: Thread2 6
System.out: Thread1 7
System.out: Thread2 8
System.out: Thread1 9
System.out: Thread2 10
于 2016-09-14T08:18:17.587 回答
0
public class EvenOddNumberPrintUsingTwoThreads {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Thread t1 = new Thread() {          
            public void run() {

                for (int i = 0; i <= 10; i++) {
                    if (i % 2 == 0) {
                        System.out.println("Even : " + i);
                    }
                }

            }
        };

        Thread t2 = new Thread() {
            // int i=0;
            public void run() {

                for (int i = 0; i <= 10; i++) {
                    if (i % 2 == 1) {
                        System.out.println("Odd : " + i);
                    }
                }

            }
        };
        t1.start();
        t2.start();
    }
}
于 2017-09-20T14:23:10.553 回答
0
package com.example;

public class MyClass  {
    static int mycount=0;
    static Thread t;
    static Thread t2;
    public static void main(String[] arg)
    {
        t2=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print(mycount++ + " even \n");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(mycount>25)
                    System.exit(0);
                run();
            }
        });
        t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.print(mycount++ + " odd \n");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if(mycount>26)
                    System.exit(0);
                run();
            }
        });
        t.start();
        t2.start();
    }
}
于 2016-06-24T09:59:50.217 回答
0
public class OddEvenPrinetr {
    private static Object printOdd = new Object();

    public static void main(String[] args) {

        Runnable oddPrinter =  new Runnable() {
            int count = 1;
            @Override
            public void run() {
                while(true){
                    synchronized (printOdd) {
                        if(count >= 101){
                            printOdd.notify();
                            return;
                        }
                        System.out.println(count);
                        count = count + 2;                                              
                        try {
                            printOdd.notify();
                            printOdd.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };


        Runnable evenPrinter =  new Runnable() {
            int count = 0;
            @Override
            public void run() {
                while(true){
                    synchronized (printOdd) {
                        printOdd.notify();
                        if(count >= 100){                       
                            return;
                        }                                       
                        count = count + 2;
                        System.out.println(count);
                        printOdd.notify();
                        try {
                            printOdd.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };

        new Thread(oddPrinter).start();
        new Thread(evenPrinter).start();
    }
}
于 2016-02-18T12:10:19.797 回答
0

公共类连续数字打印{

private static class NumberGenerator {

    public int MAX = 100;

    private volatile boolean evenNumberPrinted = true;

    public NumberGenerator(int max) {
        this.MAX = max;
    }

    public void printEvenNumber(int i) throws InterruptedException {
        synchronized (this) {
            if (evenNumberPrinted) {
                wait();
            }
            System.out.println("e = \t" + i);
            evenNumberPrinted = !evenNumberPrinted;
            notify();
        }
    }

    public void printOddNumber(int i) throws InterruptedException {
        synchronized (this) {
            if (!evenNumberPrinted) {
                wait();
            }
            System.out.println("o = \t" + i);
            evenNumberPrinted = !evenNumberPrinted;
            notify();
        }
    }

}

private static class EvenNumberGenerator implements Runnable {

    private NumberGenerator numberGenerator;

    public EvenNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for(int i = 2; i <= numberGenerator.MAX; i+=2)
            try {
                numberGenerator.printEvenNumber(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }
}

private static class OddNumberGenerator implements Runnable {

    private NumberGenerator numberGenerator;

    public OddNumberGenerator(NumberGenerator numberGenerator) {
        this.numberGenerator = numberGenerator;
    }

    @Override
    public void run() {
        for(int i = 1; i <= numberGenerator.MAX; i+=2) {
            try {
                numberGenerator.printOddNumber(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public static void main(String[] args) {
    NumberGenerator numberGenerator = new NumberGenerator(100);
    EvenNumberGenerator evenNumberGenerator = new EvenNumberGenerator(numberGenerator);
    OddNumberGenerator oddNumberGenerator = new OddNumberGenerator(numberGenerator);
    new Thread(oddNumberGenerator).start();
    new Thread(evenNumberGenerator).start();

}

}

于 2017-01-27T16:14:27.163 回答
0
public class ThreadExample {

Object lock = new Object();

class ThreadEven implements Runnable {

    @Override
    public void run() {
        int i = 2;
        while (i <= 20) {
            synchronized (lock) {
                System.out.println(i + " ");
                i = i + 2;
                lock.notify();
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

class ThreadOdd implements Runnable {

    @Override
    public void run() {
        int i = 1;
        while (i <= 20) {
            synchronized (lock) {
                System.out.println(i + " ");
                i = i + 2;
                try {
                    lock.notify();
                    lock.wait();
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }
        }

    }

}

public static void main(String args[]) {

    ThreadExample example = new ThreadExample();
    ThreadExample.ThreadOdd odd = example.new ThreadOdd();
    ThreadExample.ThreadEven even = example.new ThreadEven();

    Thread oT = new Thread(odd);
    Thread eT = new Thread(even);

    oT.start();
    eT.start();

}
于 2015-08-31T06:21:01.210 回答
0
public class MyThread {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Threado o =new Threado();
        o.start();

        Threade e=new Threade();
        e.start();    
    }    
}


class Threade extends Thread{

    public void run(){

        for(int i=2;i<10;i=i+2)
            System.out.println("evens "+i);         
    }       
}


class Threado extends Thread{

    public void run(){

        for(int i=1;i<10;i=i+2)
            System.out.println("odds "+i);          
    }       
}

输出 :-

赔率 1 赔率 3 赔率 5 赔率 7 赔率 9 偶数 2 偶数 4 偶数 6 偶数 8

于 2017-01-14T23:03:46.697 回答
0

包 p.Threads;

public class PrintEvenAndOddNum  {

    private  Object obj = new Object();

    private static final PrintEvenAndOddNum peon = new PrintEvenAndOddNum();

    private PrintEvenAndOddNum(){}

    public static PrintEvenAndOddNum getInstance(){
        return peon;
    }

    public  void printOddNum()  {
        for(int i=1;i<10;i++){
            if(i%2 != 0){
                synchronized (obj) {
                    System.out.println(i);

                    try {
                        System.out.println("oddNum going into waiting state ....");
                        obj.wait();

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println("resume....");
                    obj.notify();
                }
            }
        }
    }

    public  void printEvenNum()  {
        for(int i=1;i<11;i++){
            if(i%2 == 0){
                synchronized(obj){
                    System.out.println(i);
                    obj.notify();
                    try {
                        System.out.println("evenNum going into waiting state ....");
                        obj.wait();
                        System.out.println("Notifying waiting thread ....");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }   
}
于 2016-03-25T15:28:28.033 回答
0

如果您被要求以同步方式打印偶数奇数,那么几乎所有这些都是必要的。

public class ThreadingOddEvenNumbers {

    void main(String[] args) throws InterruptedException {
        Printer printer = new Printer(57);
        Thread t1 = new Thread(new MyRunner(printer, true), "EvenPrinter");
        Thread t2 = new Thread(new MyRunner(printer, false), "OddPrinter");
        t1.start();
        t2.start();

        t1.join();
        t2.join();
    }

}

class MyRunner implements Runnable {
    private Printer p;
    private boolean evenProperty;

    public MyRunner(Printer p, boolean evenNess) {
        this.p = p;
        evenProperty = evenNess;
    }

    public void run() {
        try {
            print();
        } catch (InterruptedException ex) {
            System.out.println(this.getClass().getName() + " "
                    + ex.getMessage());
        }
    }


    public void print() throws InterruptedException {
        while (!p.isJobComplete()) {
            synchronized (p) {
                if (evenProperty)
                    while (p.isEvenPrinted()) {
                        System.out.println("wait by: "
                                + Thread.currentThread().getName());
                        p.wait();
                        if (p.isJobComplete())
                            break;
                    }
                else
                    while (!p.isEvenPrinted()) {
                        System.out.println("wait by: "
                                + Thread.currentThread().getName());
                        p.wait();
                        if (p.isJobComplete())
                            break;
                    }
            }

            synchronized (p) {
                if (evenProperty)
                    p.printEven(Thread.currentThread().getName());
                else
                    p.printOdd(Thread.currentThread().getName());
                p.notifyAll();
                System.out.println("notify called: by: "
                        + Thread.currentThread().getName());
            }
        }
    }
}

class Printer {
    private volatile boolean evenPrinted;
    private volatile boolean jobComplete;
    private int limit;
    private int counter;

    public Printer(int lim) {
        limit = lim;
        counter = 1;
        evenPrinted = true;
        jobComplete = false;
    }

    public void printEven(String threadName) {
        System.out.println(threadName + "," + counter);
        incrCounter();
        evenPrinted = true;
    }

    public void printOdd(String threadName) {
        System.out.println(threadName + "," + counter);
        incrCounter();
        evenPrinted = false;
    }

    private void incrCounter() {
        counter++;
        if (counter >= limit)
            jobComplete = true;
    }

    public int getLimit() {
        return limit;
    }

    public boolean isEvenPrinted() {
        return evenPrinted;
    }

    public boolean isJobComplete() {
        return jobComplete;
    }
}
于 2017-07-04T15:49:54.317 回答
0

问题应该是:使用线程同时打印奇偶数

public class EvenOdd1 {
        static boolean flag = true;
        public static void main(String[] args) {
            Runnable odd = () -> {
                for (int i = 1; i <= 10;) {
                    if (EvenOddPrinter.flag) {
                        System.out.println(Thread.currentThread().getName() + " " + i);
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }//if
                }//for
            };

            Runnable even = () -> {
                for (int i = 2; i <= 10;) {
                    if (!EvenOddPrinter.flag) {
                        System.out.println(Thread.currentThread().getName() + " " + i);
                        i += 2;
                        EvenOddPrinter.flag = !EvenOddPrinter.flag;
                    }
                }
            };

            Thread t1 = new Thread(odd, "Odd");
            Thread t2 = new Thread(even, "Even");
            t1.start();
            t2.start();
        }
    }
/*The output => 
Odd 1
Even 2
Odd 3
Even 4
Odd 5
Even 6
Odd 7
Even 8
Odd 9
Even 10
*/
于 2019-04-11T06:23:33.267 回答
0

简单优雅的解决方案 -

import java.util.*;
import java.util.stream.*;  
public class OddEvenUsingTwoThreads {
   private static Object sharedObject = new Object();
   public static void main(String args[]) throws InterruptedException{
        Runnable r1 = new MyRunnable4Odd(sharedObject);
        Thread t1 = new Thread(r1);
        
        Runnable r2 = new MyRunnable4Even(sharedObject);
        Thread t2 = new Thread(r2);
        
        t1.start();
        t2.start();
        t1.join();
        t2.join();
   }   
}

class MyRunnable4Even implements Runnable{
    private Object obj;
    public MyRunnable4Even(Object sharedObj){
        this.obj = sharedObj;
    }
    @Override
    public void run() {
        for(int i=2; i<15; i+=2) {
            synchronized(obj){
              System.out.println(i);
              try{
                  obj.notify();
                  obj.wait();
              } catch(InterruptedException ie) {
                  ie.printStackTrace();
              }
            }
        }
    }
}

class MyRunnable4Odd implements Runnable{
    private Object obj;
    public MyRunnable4Odd(Object sharedObj){
        this.obj = sharedObj;
    }
    @Override
    public void run() {
        for(int i=1; i<=15; i+=2) {
            synchronized(obj){
              System.out.println(i);
              try{
                  obj.notify();
                  if(i == 15)
                    break;
                  obj.wait();
              } catch(InterruptedException ie) {
                  ie.printStackTrace();
              }
            }
        }
    }
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

解释:它不断地向两个线程打印奇数和偶数。

  • i=14MyRunnable4Even 中,打印 '14' 然后该线程通知其他等待线程并进入等待状态。
  • 在 MyRunnable4Odd 中,现在i=15被打印,通知偶数线程并关闭奇数线程(打破循环。它不会进入等待状态)。
  • 现在在 MyRunnable4Even 中,它会醒来并检查i<15,但i=16现在。所以,这个线程也完成了。
于 2021-03-21T18:22:33.537 回答