Thread、Runnable、Callable&&Future
new Thread() {
@Override
public void run() {
System.out.println("Thread实现");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable实现");
}
}).start();
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
System.out.println("Callable实现");
return "Callable的返回值";
}
};
FutureTask<String> futureTask = new FutureTask<>(callable);
new Thread(futureTask).start();
String result = futureTask.get();//Callable的返回值
其中futureTask.get()会获取callable的返回值,需要在start()方法后执行并会阻塞当前线程等待callable执行完毕
生产者消费者模式
生产消费者模式是一个十分经典的多线程协作的模式,可以实现对任务数量的控制,防止任务过多,导致程序处理不来。
简单实现等待唤醒机制
用顾客和厨师来描述消费者和生产者
厨师做好了菜,通知顾客食用,顾客吃完了叫厨师接着做!!
//生产者-厨师
class Cooker extends Thread {
@Override
public void run() {
/**
* 1.判断是否有食物
* 2.如果有就等待 || 如果没有就制作
* 3.制作完成通知顾客享用
*/
while (true) {
synchronized (Desk.lock) {
if (Desk.count == 0) {
break;
} else {
if (Desk.flag) {
try {
Desk.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("厨师正在制作食物");
Desk.flag = true;
Desk.lock.notifyAll();
}
}
}
}
}
}
//消费者-顾客
class Foodie extends Thread {
@Override
public void run() {
/**
* 1.判断是否有食物
* 2.如果没有就等待 || 如果有就吃掉
* 3.吃完之后通知厨师
*/
while (true) {
synchronized (Desk.lock) {
if (Desk.count == 0) {
break;
} else {
if (Desk.flag) {//判断是否有食物
//开始享用
System.out.println("顾客开始享用食物,当前库存" + (Desk.count-1));
Desk.flag = false;
Desk.count--;
Desk.lock.notifyAll();
} else {
//等待制作
try {
//使用什么对象作锁就必须用那个对象调用wait()和notify()
Desk.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
class Desk {
/**
* 定义一个标记判断桌子上是否有食物
* true-桌上有 顾客可以享用
* false-桌上没有 顾客需要等待
*/
public static boolean flag = false;
//每天限量5个
public static int count = 5;
//锁对象
public final static Object lock = new Object();
}
/**
* 生产者&&消费者
* 生产者==》厨师
* 消费者==》顾客
*/
Foodie foodie=new Foodie();
Cooker cooker=new Cooker();
foodie.start();
cooker.start();
厨师正在制作食物
顾客开始享用食物,当前库存4
厨师正在制作食物
顾客开始享用食物,当前库存3
厨师正在制作食物
顾客开始享用食物,当前库存2
厨师正在制作食物
顾客开始享用食物,当前库存1
厨师正在制作食物
顾客开始享用食物,当前库存0
其中notifyAll()和wait()方法,使用什么对象作锁就必须用那个对象调用
阻塞队列实现等待唤醒机制
常见BlockingQueue
ArrayBlockingQueue:底层是数组,有界
LinkedBlockingQueue:底层是链表,无界。PS:不是真正的无界,最大为int的最大值
public class Demo {
public static void main(String[] args) {
//创建一个阻塞队列
ArrayBlockingQueue<String> list = new ArrayBlockingQueue(1);
//创建线程并开启
Cooker cooker = new Cooker(list);
Foodie foodie = new Foodie(list);
cooker.start();
foodie.start();
}
}
class Cooker extends Thread {
private ArrayBlockingQueue<String> list;
private int count = 10;
public Cooker(ArrayBlockingQueue<String> list) {
this.list = list;
}
@Override
public void run() {
while (true) {
if (count == 0)
break;
try {
String food = System.currentTimeMillis() + "制作的食物";
Thread.sleep(1000);
System.out.println(food);
list.put(food);
count--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Foodie extends Thread {
private ArrayBlockingQueue<String> list;
public Foodie(ArrayBlockingQueue<String> list) {
this.list = list;
}
@Override
public void run() {
while (true)
try {
Thread.sleep(2000);
System.out.println("享用" + list.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
网友评论