需求:
三个线程,依次打印ABCABCABC....
方案一:
使用阻塞队列,线程1从队列1获取内容打印,线程2从队列2获取内容打印,线程3从队列3中获取内容打印。线程1把B放到队列3中,线程2把C放到队列3中,线程3把A放到队列1中。
demo:
demo里面防止打印太快,使用了Thread.sleep(1000),以及原子变量,记录打印次数。
PrintTask.java
import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicInteger; /** * Created by GuanXF on 2017/12/8. */ public class PrintTask { private static BlockingQueue<Character>[] blockingQueues = new BlockingQueue[]{new LinkedBlockingQueue(),new LinkedBlockingQueue(), new LinkedBlockingQueue()}; private static AtomicInteger printCount = new AtomicInteger(0); public static void main(String[] args) { Thread t1 = new Thread(new PrintA()); Thread t2 = new Thread(new PrintB()); Thread t3 = new Thread(new PrintC()); t1.start(); t2.start(); t3.start(); } static class PrintA implements Runnable{ public void run() { while(true){ try { System.out.println(blockingQueues[0].take()); blockingQueues[1].put('B'); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } static class PrintB implements Runnable{ public void run() { while(true){ try { System.out.println(blockingQueues[1].take()); blockingQueues[2].put('C'); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } static class PrintC implements Runnable{ public void run() { while(true){ try { blockingQueues[0].put('A'); System.out.println(blockingQueues[2].take()); System.out.println("----------------" + printCount.incrementAndGet() + "------------------"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
方案二:
使用整型变量记录那个值该哪个线程打印,比如 state % 3 == 0线程1打印A,state % 3 == 0线程2打印B,state % 3 == 0线程3打印C
demo
PrintTaskUseState.java
import java.util.concurrent.atomic.AtomicInteger; /** * Created by GuanXF on 2017/12/8. */ public class PrintTaskUseState { private static AtomicInteger state = new AtomicInteger(0); private static AtomicInteger printCount = new AtomicInteger(0); public static void main(String[] args) { Thread t1 = new Thread(new PrintA(), "---PrintA----"); Thread t2 = new Thread(new PrintB(), "---PrintB----"); Thread t3 = new Thread(new PrintC(), "---PrintC----"); t1.start(); t2.start(); t3.start(); } static class PrintA implements Runnable{ public void run() { while(true){ if(state.get() % 3 == 0){ System.out.println('A'); state.getAndIncrement(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } static class PrintB implements Runnable{ public void run() { while(true){ if(state.get() % 3 == 1){ System.out.println('B'); state.getAndIncrement(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } static class PrintC implements Runnable{ public void run() { while(true){ if(state.get() % 3 == 2){ System.out.println('C'); state.set(0); System.out.println("----------------" + printCount.incrementAndGet() + "------------------"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }
备注,在第二个demo使用了命名线程,可以使用jstack -l pid把进程dump下来,看到每个线程的状态,比如阻塞等。这是一个很好的方法。