【数据结构和算法】A,B,C三个线程,让3个线程按ABC顺序输出,输出10遍,线程退出
一、基于阻塞队列和计数器的方式实现
package com.sxf.study.interview.algorithm; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * */ public class ThreadTest { public static void main(String[] args) { /** * 声明队列 */ LinkedBlockingQueue<String> linkedBlockingQueueA_C =new LinkedBlockingQueue<>(); LinkedBlockingQueue<String> linkedBlockingQueueA_B =new LinkedBlockingQueue<>(); LinkedBlockingQueue<String> linkedBlockingQueueB_C =new LinkedBlockingQueue<>(); /** * 声明线程 */ ThreadA threadA=new ThreadA(linkedBlockingQueueA_C,linkedBlockingQueueA_B); ThreadB threadB=new ThreadB(linkedBlockingQueueA_B,linkedBlockingQueueB_C); ThreadC threadC=new ThreadC(linkedBlockingQueueB_C,linkedBlockingQueueA_C); /** * 启动线程 */ threadA.start(); threadB.start(); threadC.start(); /** * 向A线程的消费队列里放入1个元素,启动程序 */ try { linkedBlockingQueueA_C.put("C"); } catch (InterruptedException e) { e.printStackTrace(); } } } class ThreadA extends Thread{ private AtomicInteger count=new AtomicInteger(0); private LinkedBlockingQueue<String> linkedBlockingQueueA_C; private LinkedBlockingQueue<String> linkedBlockingQueueA_B; public ThreadA(LinkedBlockingQueue<String> linkedBlockingQueueA_C,LinkedBlockingQueue<String> linkedBlockingQueueA_B){ this.linkedBlockingQueueA_C=linkedBlockingQueueA_C; this.linkedBlockingQueueA_B=linkedBlockingQueueA_B; } @Override public void run() { while (true){ String a; try { //消费C线程的生产 a=linkedBlockingQueueA_C.poll(1, TimeUnit.SECONDS); //如果为空,则代表为超时,则判断计数器是否满足,如满足退出线程,如不满足则继续消费等待数据 //如果不为空,则代表为C线程生产的数据,则向下执行 if(a==null){ if(count.get()>=10){ break; }else { continue; } } } catch (InterruptedException e) { e.printStackTrace(); } //计数器小于10,表示为打印到10次 if(count.get()<10){ //打印线程名 System.out.println("A"); //计数器+1 count.incrementAndGet(); try { //唤醒B线程打印数据 linkedBlockingQueueA_B.put("A"); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class ThreadB extends Thread{ private AtomicInteger count=new AtomicInteger(0); private LinkedBlockingQueue<String> linkedBlockingQueueA_B; private LinkedBlockingQueue<String> linkedBlockingQueueB_C; public ThreadB( LinkedBlockingQueue<String> linkedBlockingQueueA_B,LinkedBlockingQueue<String> linkedBlockingQueueB_C){ this.linkedBlockingQueueA_B=linkedBlockingQueueA_B; this.linkedBlockingQueueB_C=linkedBlockingQueueB_C; } @Override public void run() { while (true){ String a; try { a=linkedBlockingQueueA_B.poll(1, TimeUnit.SECONDS); if(a==null){ if(count.get()>=10){ break; }else { continue; } } } catch (InterruptedException e) { e.printStackTrace(); } if(count.get()<10){ System.out.println("B"); count.incrementAndGet(); try { linkedBlockingQueueB_C.put("B"); } catch (InterruptedException e) { e.printStackTrace(); } } } } } class ThreadC extends Thread{ private AtomicInteger count=new AtomicInteger(0); private LinkedBlockingQueue<String> linkedBlockingQueueB_C; private LinkedBlockingQueue<String> linkedBlockingQueueA_C; public ThreadC(LinkedBlockingQueue<String> linkedBlockingQueueB_C,LinkedBlockingQueue<String> linkedBlockingQueueA_C){ this.linkedBlockingQueueB_C=linkedBlockingQueueB_C; this.linkedBlockingQueueA_C=linkedBlockingQueueA_C; } @Override public void run() { while (true){ String a; try { a=linkedBlockingQueueB_C.poll(1, TimeUnit.SECONDS); if(a==null){ if(count.get()>=10){ break; }else { continue; } } } catch (InterruptedException e) { e.printStackTrace(); } if(count.get()<10){ System.out.println("C"); count.incrementAndGet(); try { linkedBlockingQueueA_C.put("C"); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
二、基于状态机锁进行实现
package com.sxf.study.interview.algorithm; /** * */ public class ThreadABCThread { public static void main(String[] args) { ThreadDispatch threadDispatch = new ThreadDispatch(); MyThread threadA = new MyThread(threadDispatch,0,"A"); MyThread threadB = new MyThread(threadDispatch,1,"B"); MyThread threadC = new MyThread(threadDispatch,2,"C"); threadA.start(); threadB.start(); threadC.start(); } } class MyThread extends Thread { private String printName; private int process; private ThreadDispatch dispatch; public MyThread(ThreadDispatch dispatch, int process, String printName) { this.dispatch = dispatch; this.process = process; this.printName = printName; } @Override public void run() { //获取线程调度器的锁 synchronized (dispatch) { //一个线程执行10次退出 for (int i = 0; i < 10; i++) { int state = dispatch.getState(); //直到为当前线程要执行的状态,才会继续执行 while (state != process) { try { //释放锁,进入等待区,等待其他获取该锁的线程进行唤醒 dispatch.wait(); } catch (InterruptedException e) { e.printStackTrace(); } //重新获取锁后,再次获取调度器的状态 state=dispatch.getState(); } //打印线程名字 System.out.println(printName); //更新锁,让其他线程执行 dispatch.update(); //唤醒其他进入等待区的线程 dispatch.notifyAll(); } } } } /** * 线程调度状态机 */ class ThreadDispatch { /** * 状态机 * 0==>a线程执行 * 1==>b线程执行 * 2==>c线程执行 */ private int state = 0; public int getState() { return state; } public void update() { state = (++state) % 3; } }