一、基于阻塞队列实现生产者和消费者循环生产消费。
1、解题思路基于自定义线程+ArrayBlockQuery实现
1.1 生产者
package com.boot.skywalk.util.queue;
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable{
private BlockingQueue<Menu> blockingQueue;
public Producer(BlockingQueue blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run() {
for(int i=1;i<=100;i++){
Menu menu = new Menu(i + "code");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
blockingQueue.put(menu);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("生产商品:"+menu.getMessage());
}
// 作为退出标记
Menu exit = new Menu("exit");
try {
blockingQueue.put(exit);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
1.2 消费者
package com.boot.skywalk.util.queue;
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Menu> blockingQueue;
public Consumer(BlockingQueue blockingQueue){
this.blockingQueue=blockingQueue;
}
@Override
public void run() {
Menu menu;
try {
while(!(menu=blockingQueue.take()).getMessage().equals("exit")){
Thread.sleep(100);
System.out.println("消费商品:"+menu.getMessage());
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
1.3 测试代码
package com.boot.skywalk.util.queue;
public class Menu {
private String message;
public Menu(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
package com.boot.skywalk.util.queue;
import java.util.concurrent.ArrayBlockingQueue;
public class Client {
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(10);
Producer producer = new Producer(blockingQueue);
Consumer consumer = new Consumer(blockingQueue);
System.out.println("消费开始");
Thread produceThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
produceThread.start();
consumerThread.start();
produceThread.join();
consumerThread.join();
System.out.println("消费结束");
}
}
运行结果
二、多个线程顺序执行
1、解题思路基于CountDownLatch的countDown和await实现.
package com.boot.skywalk.thread;
import com.boot.skywalk.exception.GlobalException;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 线程工具类封装,ThreadUtil
*/
@Slf4j
public final class ThreadUtil {
/**
* Number of milliseconds in a standard second.
*/
public static final long MILLIS_PER_SECOND = 1000;
/**
* Number of milliseconds in a standard minute.
*/
public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
/**
* Number of milliseconds in a standard hour.
*/
public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
/**
* Number of milliseconds in a standard day.
*/
public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;
/**
* 校验时间单位
*
* @param duration duration
* @param unit unit
*/
public static void checkDurationLength(long duration, TimeUnit unit){
long durationSeconds = TimeUnit.MILLISECONDS.convert(duration, unit);
if(durationSeconds<0||durationSeconds>MILLIS_PER_DAY){
log.error("illegal duration time,duration={},unit={}",duration,unit);
throw new GlobalException("duration time is illegal");
}
}
/**
* 毫秒级中断线程
*
* @param millSeconds
*/
public static void pauseThreadMillSeconds(long millSeconds){
pauseThread(millSeconds, TimeUnit.MILLISECONDS);
}
/**
* 秒级中断线程
*
* @param seconds
*/
public static void pauseThreadSeconds(long seconds){
pauseThread(seconds, TimeUnit.SECONDS);
}
/**
* 中断线程
*
* @param duration duration
* @param unit unit
*/
public static void pauseThread(long duration,TimeUnit unit){
if(Objects.isNull(unit)){
log.error("TimeUnit is null");
throw new GlobalException("TimeUnit is null");
}
checkDurationLength(duration, unit);
try {
unit.sleep(duration);
} catch (InterruptedException e) {
log.error("pause thread fail,duration={},unit={}",duration,unit,e);
}
}
// 使用
public static void main(String[] args) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static CountDownLatch countDownLatch1 = new CountDownLatch(1);
private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
private static CountDownLatch countDownLatch3 = new CountDownLatch(1);
// 基于CountDownLatch实现
public static void test4(){
// Thread1
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread1 Run");
countDownLatch1.countDown();
}
});
// Thread2
final Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread2 Run");
countDownLatch2.countDown();
}
});
// Thread3
final Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread3 Run");
countDownLatch3.countDown();
}
});
// Thread4
final Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread4 Run");
}
});
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
运行如下:
2、基于线程join实现.
public static void test1(){
// Thread1
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread1 Run");
}
});
final Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread2 Run");
}
});
final Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread3 Run");
}
});
final Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
try {
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread4 Run");
}
});
// 线程执行
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
3、多个子线程交替start()+join()
public static void test2() throws InterruptedException {
// Thread1
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread1 Run");
}
});
// Thread2
final Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread2 Run");
}
});
// Thread3
final Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread3 Run");
}
});
// Thread4
final Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread4 Run");
}
});
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
thread3.join();
thread4.start();
thread4.join();
}
4、单个线程依次提交
public static void test3(){
// Thread1
final Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread1 Run");
}
});
// Thread2
final Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread2 Run");
}
});
// Thread3
final Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread3 Run");
}
});
// Thread4
final Thread thread4 = new Thread(new Runnable() {
@Override
public void run() {
ThreadUtil.pauseThreadSeconds(1);
System.out.println("Thread4 Run");
}
});
singleThreadEventExecutor.execute(thread1);
singleThreadEventExecutor.execute(thread2);
singleThreadEventExecutor.execute(thread3);
singleThreadEventExecutor.execute(thread4);
singleThreadEventExecutor.shutdown();
}
三、多个线程交替打印
1、synchionized+volatile+对象锁+等待通知机制。
private int times;
private volatile int state;
private static final Object LOCK = new Object();
public SynchionizedTest(int times) {
this.times = times;
}
public static void main(String[] args) {
SynchionizedTest printABC = new SynchionizedTest(20);
new Thread(printABC::printA).start();
new Thread(printABC::printB).start();
new Thread(printABC::printC).start();
}
public void printA() {
try {
print("A", 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printB() {
try {
print("B", 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void printC() {
try {
print("C", 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void print(String name, int targetState) throws InterruptedException {
for (int i = 0; i < times; i++) {
synchronized (LOCK) {
while (state % 3 != targetState) {
LOCK.wait();
}
state++;
ThreadUtil.pauseThreadSeconds(1);
System.out.println(name);
LOCK.notifyAll();
}
}
}
}
四、多个线程等待某一个线程的信号,同时开始执行
// 在这段代码中,首先打印出了运动员有 5 秒的准备时间,然后新建了一个 CountDownLatch,其倒数值只有 1;接着,同样是一个 5 线程的线程池,并且用 for 循环的方式往里提交 5 个任务,而这 5 个任务在一开始时就让它调用 await() 方法开始等待。
public static void countLatch (){
System.out.println("运动员有5秒的准备时间");
CountDownLatch countDownLatch = new CountDownLatch(1);
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
final int no = i + 1;
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(no + "号运动员准备完毕,等待裁判员的发令枪");
try {
countDownLatch.await();
System.out.println(no + "号运动员开始跑步了");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
service.submit(runnable);
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("5秒准备时间已过,发令枪响,比赛开始!");
countDownLatch.countDown();
service.shutdown();
}
五、一个线程等待多个线程完成各自工作后再进行工作
private static void extractedLatch() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(5);
ExecutorService service = Executors.newFixedThreadPool(5);
for (int i = 0; i < 5; i++) {
final int no = i + 1;
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println(no + "号运动员完成了比赛。");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
};
service.submit(runnable);
}
System.out.println("等待5个运动员都跑完.....");
latch.await();
service.shutdown();
System.out.println("所有人都跑完了,比赛结束。");
}
运行截图.