public static void main(String[] args) {
Thread thread=new Thread(new ExceptionThread());
thread.setUncaughtExceptionHandler(new MyExceptionHandler());
thread.start();
}
}
/**
- 任务类
\*/
class ExceptionThread implements Runnable{
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println("ExceptionThread 当前线程信息:"+t.toString());
System.out.println("当前线程ExceptionThread的异常处理器"
+t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
/**
- 线程异常处理器
\*/
class MyExceptionHandler implements Thread.UncaughtExceptionHandler {[br/>@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("抛出的异常是:"+e);
}
}](mailto:br/)
8、共享资源
共享资源竞争:
导致线程安全问题
解决思想:
多人(线程)都希望单独使用浴室(共享资源)。为了使用浴室,一个人先敲门,看能不能使用。如果没人回话,他就进入浴室并锁上门(获得锁)。这时候,其它人想使用浴室的话,就会被阻挡在外面(不能获取锁),直到浴室可以使用。浴室外面的人没有排队,浴室门打开(前一个人释放锁),离门最近的人优先进入使用(获得锁,设置优先级和yield方法可以建议某个优先使用)。
解决方式:
Synchronized 、Lock锁同步以及Voliate修饰符和原子类
线程本地存储—ThreadLocal
9、线程之间协作
生产者与消费者
package com.duoxiancheng;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
- 生产者-消费者
\*/
public class Main3 {
public static void main(String\[ \] args) throws InterruptedException {
Restaurant restaurant=new Restaurant();
new Thread(new ProductorThread(restaurant)).start();
Thread.sleep(20);
new Thread(new ConsumerThread(restaurant)).start();
}
}
class Restaurant {
Lock lock=new ReentrantLock();//锁
Condition condition1=lock.newCondition();//条件1
Condition condition2=lock.newCondition();//条件2
private int count;//已做好的餐
private int count2;
/\*\*
* 消费者方法
\*/
public void comsumer(){
lock.lock();
try {
if (count==0) {
System.out.println(Thread.currentThread().getId()+"客户 想要一份快餐!");
condition2.signalAll();
System.out.println(Thread.currentThread().getId()+"客户 等待一份快餐!");
condition1.await();
}
count--;
System.out.println(Thread.currentThread().getId()+ "客户 消费了一份快餐!");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
/\*\*
* 生产者方法
\*/
public void productor(){
lock.lock();
try {
condition2.await();
count++;//生产一份快餐
System.out.println(Thread.currentThread().getId()+ "厨师 制作了一份快餐!");
condition1.signalAll();
System.out.println(Thread.currentThread().getId()+"厨师 通知客户使用");
}catch (InterruptedException e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
/**
- 消费者
\*/
class ConsumerThread implements Runnable{
private Restaurant restaurant;
public ConsumerThread(Restaurant restaurant){
this.restaurant=restaurant;
}
@Override
public void run() {
restaurant.comsumer();
}
}
/**
- 生产者
\*/
class ProductorThread implements Runnable{
private Restaurant restaurant;
public ProductorThread(Restaurant restaurant){
this.restaurant=restaurant;
}
@Override
public void run() {
restaurant.productor();
}
}
输出结果:
11客户 想要一份快餐!
11客户 等待一份快餐!
10厨师 制作了一份快餐!
10厨师 通知客户使用
11客户 消费了一份快餐!
生产者与消费者 和 队列
使用wait()、notifyAll() 是一种解决任务互操作问题非常低级的方式。使用同步队列来解决任务协作问题,同步队列在任何时刻只允许一个任务插入或移除。
java.util.concurrent.BlockingQueue接口提供了这个同步队列,其有大量的实现。通常可以使用LinkedBlockingDeque(×××队列) 和 ArrayBlockingDeque(固定尺寸队列)。
消费者任务试图从队列中获取对象,而该队列此时为空,那这些队列还可以挂起消费者任务(阻塞);当有更多元素可用时恢复消费者任务。阻塞队列可以解决非常大量的问题。
package com.duoxiancheng;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
/**
- 生产者-消费者与队列
\*/
public class Main4 {
public static void main(String\[\] args) {
ExecutorService executorService= Executors.newCachedThreadPool();
LinkedBlockingDeque<Toast> toastQueue=new LinkedBlockingDeque<>();
LinkedBlockingDeque<Toast> butteredQueue=new LinkedBlockingDeque<>();
LinkedBlockingDeque<Toast> jammedQueue=new LinkedBlockingDeque<>();
executorService.execute(new Toaster(toastQueue));
executorService.execute(new Butterer(toastQueue, butteredQueue));
executorService.execute(new Jammed(butteredQueue, jammedQueue));
executorService.execute(new Eater(jammedQueue));
}
}
class Toast{
private Status status=Status.DRY;
private final int id;
public Toast(int id) {
this.id = id;
}
public int getId() {
return id;
}
public Status getStatus() {
return status;
}
public void addButtered(){
status=Status.BUTTERED;
}
public void addJammed(){
status=Status.JAMMED;
}
@Override
public String toString() {
return "Toast "+id+" : "+status;
}
/**
- 枚举类型
*/
public enum Status{
DRY,BUTTERED,JAMMED
}
}
/**
- 制作吐司
\*/
class Toaster implements Runnable{
private LinkedBlockingDeque<Toast> toastQueue;
private int count;
public Toaster(LinkedBlockingDeque toastQueue){[br/>this.toastQueue=toastQueue;
}
@Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
Toast toast = new Toast(count++);
System.out.println(toast);
toastQueue.put(toast);
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}](mailto:br/)
/**
- 添加黄油
\*/
class Butterer implements Runnable{
private LinkedBlockingDeque<Toast> toastQueue;
private LinkedBlockingDeque<Toast> butteredQueue;
public Butterer(LinkedBlockingDeque toastQueue,LinkedBlockingDeque butteredQueue){[br/>this.toastQueue=toastQueue;
this.butteredQueue=butteredQueue;
}
@Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
Toast toast = toastQueue.take();
toast.addButtered();
System.out.println("添加黄油, " + toast);
butteredQueue.put(toast);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}](mailto:br/)
/**
- 添加果酱
\*/
class Jammed implements Runnable{
private LinkedBlockingDeque<Toast> butteredQueue;
private LinkedBlockingDeque<Toast> jammedQueue;
public Jammed(LinkedBlockingDeque butteredQueue, LinkedBlockingDeque jammedQueue){[br/>this.butteredQueue=butteredQueue;
this.jammedQueue=jammedQueue;
}
@Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
Toast toast = butteredQueue.take();
toast.addJammed();
System.out.println("添加果酱, " + toast);
jammedQueue.put(toast);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}](mailto:br/)
/**
- 消费吐司
\*/
Java高频面试专题合集解析:
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
更多Java架构进阶资料展示
System.out.println("添加果酱, " + toast);
jammedQueue.put(toast);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}](mailto:br/)
/**
- 消费吐司
\*/
Java高频面试专题合集解析:
[外链图片转存中…(img-c0MRqQXh-1714321202948)]
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
[外链图片转存中…(img-udfBfnZ6-1714321202949)]
更多Java架构进阶资料展示
[外链图片转存中…(img-EY0Vq6Wf-1714321202949)]
[外链图片转存中…(img-rKCuQJ0j-1714321202949)]
[外链图片转存中…(img-Q1ys4Ebl-1714321202950)]