用2个线程编写程序,交替打印

我最近在接受采访时被问到这个问题。

编写一个带有两个线程(A和B)的程序,其中A打印1,B打印2,依此类推,直到达到50。

我们该怎么做呢?

赋值的本质是演示线程如何发出另一个线程的信号。 最常见的方法是使用阻塞队列,但这里信号不携带任何信息,因此信号量就足够了。

创建用2个信号量参数化的线程类:输入和输出:

class ThreadPrinter implements Runnable { int counter; Semaphore ins, outs; ThreadPrinter(int counter, Semaphore ins, Semaphore outs) { this.counter = counter; this.ins = ins; this.outs = outs; } @Override public void run() { for (int i = 0; i < 25; i++) { ins.aquire(); // wait for permission to run System.out.println("" + counter); outs.release(); // allow another thread to run counter += 2; } } 

创建2个Semaphore并将它们传递给2个线程:

 Semaphore a = new Semaphore(1); // first thread is allowed to run immediately Semaphore b = new Semaphore(0); // second thread has to wait ThreadPrinter tp1 = new ThreadPrinter(1, a, b); ThreadPrinter tp2 = new ThreadPrinter(2, b, a); 

注意信号量ab以不同的顺序传递。

 public class Test { private static int count = 0; public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 25; i++) { synchronized (CommonUtil.mLock) { incrementCount(); CommonUtil.mLock.notify(); try { CommonUtil.mLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 25; i++) { synchronized (CommonUtil.mLock) { incrementCount(); CommonUtil.mLock.notify(); try { CommonUtil.mLock.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }); t1.start(); Thread.sleep(400); t2.start(); t1.join(); t2.join(); } private static void incrementCount() { count++; System.out.println("Count: " + count + " icnremented by: " + Thread.currentThread().getName()); } } class CommonUtil { static final Object mLock = new Object(); } 

我遇到了同样的问题,并且预计只使用基础知识,所以我选择在线程之间的共享对象上等待通知

 public class Message implements Runnable { private static final int N = 10; private Thread thread; private static Object object = new Object(); public Message(String name){ thread = new Thread(this, name); thread.start(); } public void run(){ for(int i=0; i 

主要方法:

 Message message1 = new Message("Ping"); Message message2 = new Message("Pong"); 

这是另一种解决方案:

  Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized (lock) { for (int i = 1; i <= 50; i += 2) { System.out.println("T1=" + i); t1turn = false; try { lock.notifyAll(); lock.wait(); } catch (InterruptedException e) { } } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized (lock) { for (int i = 2; i <= 50; i += 2) { if (t1turn) try { lock.wait(); } catch (InterruptedException e) { } System.out.println("T2=" + i); t1turn = true; lock.notify(); } } } }); t1.start(); t2.start(); 

可能这仍然是相关的:

 public class MyRunnable implements Runnable { public static int counter = 0; public static int turn = 0; public static Object lock = new Object(); @Override public void run() { while (counter < 50) { synchronized (lock) { if (turn == 0) { System.out.println(counter + " from thread " + Thread.currentThread().getName()); turn = 1; try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } else { turn = 0; lock.notify(); } } } } } 

然后是主要function

 public static void main(String[] args) { Thread threadA = new Thread(new MyRunnable()); Thread threadB = new Thread(new MyRunnable ()); threadA.start(); threadB.start(); } 
 public class PingPong extends Thread { static StringBuilder object = new StringBuilder(""); public static void main(String[] args) throws InterruptedException { Thread t1 = new PingPong(); Thread t2 = new PingPong(); t1.setName("\nping"); t2.setName(" pong"); t1.start(); t2.start(); } @Override public void run() { working(); } void working() { while (true) { synchronized (object) { try { System.out.print(Thread.currentThread().getName()); object.notify(); object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } 

}

 public class ThreadCounter implements Runnable { private static int count = 0; private Thread t; public ThreadCounter(String tName){ t= new Thread(this, tName); t.start(); } @Override public void run() { for(int i=1; i<=5; i++){ synchronized (CommonUtil.mLock) { incrementCount(t.getName()); CommonUtil.mLock.notify(); try { CommonUtil.mLock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } private void incrementCount(String tName){ System.out.println(tName+": "+(++ThreadCounter.count)); } public static void main(String[] args) throws InterruptedException { new ThreadCounter("Thread1"); Thread.sleep(500); new ThreadCounter("Thread2"); } } class CommonUtil{ public static Object mLock = new Object(); } 

这是最简单的解决方案,我能够想到。 它使用synchronized方法并使用notify()和wait()来交替打印数字。 希望能帮助到你。 🙂

  public class program implements Runnable { static int count =1; private static final int MAX_COUNT = 50; public synchronized void print () { System.out.println(Thread.currentThread().getName() + " is printing " + count); count++; notify(); try{ if(count>MAX_COUNT) return; wait(); }catch (InterruptedException e){ e.printStackTrace(); } } public void run() { for(int i=0;i 
 //simply use wait and notify and and set a counter and it will do public class ThreadalternatePrint implements Runnable { static int counter =0; @Override public synchronized void run() { try { Thread.sleep(10); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while(counter<51) { ++counter; notify(); System.out.println(Thread.currentThread().getName()); try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { ThreadalternatePrint obj1 = new ThreadalternatePrint(); Thread Th1 = new Thread(obj1); Thread Th2 = new Thread(obj1); Th1.setName("Thread1"); Th2.setName("Thread2"); Th1.start(); Th2.start(); } } 
 public class Testing implements Runnable { private static int counter = 1; private static final Object lock = new Object(); public static void main(String[] args) { Thread t1 = new Thread(new Testing(), "1"); t1.start(); Thread t2 = new Thread(new Testing(), "2"); t2.start(); } @Override public void run() { while (counter<=100) { synchronized (lock) { if (counter % 2 == 0) { System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName()); counter++; try { lock.notifyAll(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else if (counter % 2 == 1) { System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName()); counter++; try { lock.notifyAll(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } 

我想这可能会有所帮助。 虽然它不标准但我希望它提供一种更简单的方法。

 public class ThreadDemo { public static void main (String [] args) { PrintDemo pd=new PrintDemo(); MyThread1 mt1 = new MyThread1 ("T1",pd); MyThread2 mt2 = new MyThread2 ("T2",pd); mt1.start (); mt2.start(); } } class PrintDemo { private boolean oddFlag=true; public synchronized void printOdd(int i,String tName){ if(oddFlag==false){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else{ System.out.println("\nThread "+tName+" count:"+i); oddFlag=false; notify(); } } public synchronized void printEven(int i,String tName){ if(oddFlag==true){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else{ System.out.println("\nThread "+tName+" count:"+i); oddFlag=true; notify(); } } } class MyThread1 extends Thread { private PrintDemo pd; private String name; MyThread1(String threadName,PrintDemo pd){ this.name=threadName; this.pd=pd; } public void run () { for(int i=1;i<=50;i+=2){ pd.printOdd(i,name); } } } class MyThread2 extends Thread { private PrintDemo pd; private String name; MyThread2(String threadName,PrintDemo pd){ this.name=threadName; this.pd=pd; } public void run () { for(int i=2;i<=50;i+=2){ pd.printEven(i,name); } } }