创建两个线程,一个显示奇数和其他偶数

我正在尝试创建两个线程,一个线程显示从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); } } } 

我只想更改一些细节(这里不需要使用模运算符……):

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

@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) { } } } 

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

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

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

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

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

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

是的没关系。 但在这种情况下,我认为你不需要2个线程,因为操作很简单。 但是,如果您正在练习线程,那就没关系

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

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

 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完成t2完成t1

如果你想要替代方案,我还会考虑使用Java Concurrency 。 Java Concurrency包中提供的一些function提供了更高级别的抽象,然后直接使用Thread类并提供更多function。

对于您的具体情况,您的行为是否合理,但这些数字的打印顺序是否重要? 在赔率之前你想要均衡吗? 这些问题更能说明最符合您需求的设计。

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

并发包:

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

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

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

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

Nos将按顺序打印

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

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

公共类ConsecutiveNumberPrint {

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

}

 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个均衡5个均衡4个均衡6个均衡8

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

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