本文参考自大佬 公众号:路人甲java
添加链接描述
饥饿是指某一个或者多个线程因为种种原因无法获得所要的资源,导致一直无法执行。比如它的优先级可能太低,而高优先级的线程不断抢占它需要的资源,导致低优先级线程无法工作
package juc;
import java.util.concurrent.*;
/**
* @author yanjun.liu
* @date 2020/6/19--17:57
* 饥饿锁
*/
public class A {
/**
* 获取一个单例线程池,只有一个线程,任何有序执行,先到先执行
* 这个线程会保证你的任务执行完成,如果当前线程意外终止,会创建一个新线程继续执行任务
*/
private static ExecutorService single=Executors.newSingleThreadExecutor();
public static class AnotherCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("in AnotherCallable");
return "another- success";
}
}
public static class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("in MyCallable");
//因为线程池中只有一个线程,执行下一行代码的时候,需要重新启动一个线程去执行
//但是唯一的线程已经被new MyCallable();所占用,所以下面一行代码,没有线程,也就无法继续往下执行,线程阻塞(程序死锁)
Future<String> submit = single.submit(new AnotherCallable());
return submit.get();
}
}
public static void main(String[] args) throws Exception {
MyCallable myCallable = new MyCallable();
Future<String> submit = single.submit(myCallable);
System.out.println(submit.get());
System.out.println("over");
single.shutdown();
}
}
最后执行结果
in MyCallable
newSingleThreadExecutor 创建只有一个线程的线程池,看看它的构造函数
初始线程数为1,最大线程数1,空闲线程数在多长时间内没任务会被回收参数为0,new LinkedBlockingQueue(),如果不指定容量,默认为Integer.MAX_VALUE,也就是无界队列,一直可以放,直至内存爆炸。。。,可以手动设置大小避免
根据线程池的执行顺序,初始线程不够用,放队里,队里不够用,创建最大线程数,最大线程数满了,使用拒绝策列,拒绝任务,所以这个线程池,只会有一个线程执行
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}