线程池的原理类似于用碗吃饭,吃完后放回橱柜(就是线程池),如果这个碗正在使用(A线程),这时需要新的线程B执行,则从橱柜里重新拿碗,如果A线程使用的碗还未归还则需要拿新的碗进行吃饭;
//创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
//static ExecutorService newCachedThreadPool()
//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPool {public static void main(String[] args) throws InterruptedException {//创建一个默认线程池对象 默认是空的 默认最大是int的最大值ExecutorService executorService = Executors.newCachedThreadPool();//Executors 帮助我们创建线程池对象//ExecutorService 帮追我们管理线程池executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});// Thread.sleep(2000);executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();}}
此时之所以是两个线程执行因为线程1执行完还未归还线程池内时,线程2已经执行,所以时两个线程对象
执行结果
执行时后睡2s后执行,由一个线程对象执行的
newFixedThreadPool(10) 这里的值 是线程池的最大值
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)
public class ThreadPool2 {public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(10);executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();}
}//获取最大线程池容量import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;//创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
//static ExecutorService newFixedThreadPool(int nThreads)
public class ThreadPool2 {public static void main(String[] args) {//参数不是初始值 而是最大值ExecutorService executorService = Executors.newFixedThreadPool(10);ThreadPoolExecutor pool=(ThreadPoolExecutor) executorService;System.out.println(pool.getPoolSize());executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.submit(()->{System.out.println(Thread.currentThread().getName()+"在执行了");});executorService.shutdown();System.out.println(pool.getPoolSize());}
}
代码实现
//ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
// BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
// 创建一个新 ThreadPoolExecutor给定的初始参数。import java.util.concurrent.*;/**** 参数1:核心线程数量* 参数2:最大线程数* 参数3:空闲线程最大存活时间* 参数4:时间单位* 参数5:任务队列 如下最大执行为5个线程,超过5个线程时就要在队列中等待* 参数6:任务创建工厂 按照默认方式创建线程对象 源码中还是new Thread()* 参数7:任务拒绝策略 什么时候拒绝任务? 当提交任务>池子中最大线程数量+任务队列容量 怎样拒绝任务?? * 4种拒绝任务策略*/
public class ThreadPool3 {static class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());pool.submit(new MyRunnable());pool.submit(new MyRunnable());pool.shutdown();}
}
超过线程池中线程最大容量+任务队列容量时:丢弃任务并抛出异常
代码实现
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/**** 参数1:核心线程数量* 参数2:最大线程数* 参数3:空闲线程最大存活时间* 参数4:时间单位* 参数5:任务队列* 参数6:任务创建工厂* 参数7:任务拒绝策略*/
public class ThreadPool4 {static class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());for (int i = 1; i <= 16; i++) {pool.submit(new MyRunnable());}pool.shutdown();}
}
直接丢弃 不抛异常
public class ThreadPool4 {static class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"在执行了");}}public static void main(String[] args) {ThreadPoolExecutor pool=new ThreadPoolExecutor(1,2,2,TimeUnit.SECONDS,new ArrayBlockingQueue<>(1),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());for (int i = 1; i <= 5; i++) {int y=i;pool.submit(()->{
System.out.println(Thread.currentThread().getName()+"*****"+y);});}pool.shutdown();}
}
执行结果:
抛弃队列中等待最久,加入当前任务进入队列
直接放结果
强制线程每次使用的时候,都会看一下共享区域最新的值
对 volatile 修饰的变量值,保证线程读取到的值是最新的,而不是寄存器中缓存的值。
class Money {public static volatile int money=100000;public static void main(String[] args) {MyThead1 t1=new MyThead1();MyThead2 t2=new MyThead2();t2.start();t1.start();}
}
class MyThead2 extends Thread{
@Override
public void run() {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}Money.money=90000;}}public class MyThead1 extends Thread{@Overridepublic void run() {while (Money.money==100000){}System.out.println("结婚基金已经不是10万了");}
}
代码实现:
class Money {public static volatile int money = 100000;public static Object lock = new Object();public static void main(String[] args) {MyThead1 t1 = new MyThead1();MyThead2 t2 = new MyThead2();t2.start();t1.start();}
}class MyThead2 extends Thread {@Overridepublic void run() {synchronized (Money.lock){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}Money.money = 90000;}}
}public class MyThead1 extends Thread {@Overridepublic void run() {while (true) {synchronized (Money.lock) {if (Money.money != 100000) {System.out.println("结婚基金已经不是10万了");break;}}}}
}
原理:
上一篇:XGBoost详解(原理篇)
下一篇:Javaweb国际化解决方案