Java多线程(线程池)
线程池
标准库线程池
ThreadPoolExector,使用起来比较复杂,构造方法中,包含很多参数。
参数的意义:
int corePoolSize,int maximumPoolSize
(核心线程数) (最大线程数)
标准库的线程池是这样设定的
把线程分成两类:
1)核心线程(正式员工) corePoolSize
2)非核心线程(临时工/实习生)maximumPoolSize 就是核心线程数+非核心线程数
1核心线程数)
(单位s,分钟,小时,毫秒......)
非核心线程,允许空闲的最大时间,非核心线程,要在线程池不忙的时候,回收掉,不是立即回收。
2任务队列)
线程池的任务队列
线程池会提供submit方法,让其他线程把任务提交给线程池。
线程池内部需要有一个队列这样的数据结构,把要执行的任务保存起来。
后续线程池内部的工作线程,就会消费这个队列,从而来完成具体的任务执行。
3工厂模式)
工厂模式,也是一种设计模式
主要是解决,基于构造方法创建对象太坑了的问题。
核心思路(不再使用构造方法创建对象,给构造方法包装一层)
package Thread;
class Point{
public static Point makexy(){
Point t=new Point();
t.setX(x);
t.setY(y);
return t;
}
public static Point makexr(){
Point t=new Point();
t.setX(x);
t.setR(r);
return t;
}
}
public class Demo20 {
public static void main(String[] args) {
Point dex=Point.makexr();
Point dex1=Point.makexy();
}
}
4拒绝策略)
拒绝策略,其实是一个枚举类型,有三种策略。
直接抛出异常(让程序员快速的知道,任务处理不过来了,代码罢工了)
别人给我,我这慢了,你自己来执行。谁负责添加任务,谁负责执行任务,线程池本身,不管了。
丢弃掉最老的任务,让新的任务去队列中排队。
丢弃最新的任务,还是按照原有的节奏来执行。
接下来我们自制一个线程池
package Thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
//写一个简单的线程池
class MyThreadPool{
//最大容量为1000
private BlockingQueue<Runnable> queue=new ArrayBlockingQueue<>(1000);
private int maxPoolSize=0;
private List<Thread> threadList=new ArrayList<>();
//初始化线程池(FixedThreadPool)
public MyThreadPool(int corePoolSize,int maxPoolSize){
this.maxPoolSize=maxPoolSize;
//创建若干个线程
for (int i = 0; i < corePoolSize; i++) {
Thread t=new Thread(() ->{
try {
while(true) {
Runnable runnable = queue.take();
runnable.run();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
threadList.add(t);
}
}
void submit(Runnable runnable) throws InterruptedException {
//此处进行判定,判定说当前任务队列的元素个数,是否比较长
//如果队列元素比较长,说明已有的线程,不太能处理过来了,创建新的线程即可
//如果队列不是很长,没必要创建新的线程。
queue.put(runnable);
if(queue.size()>=500&&threadList.size()<maxPoolSize){
Thread t=new Thread(() ->{
try {
while(true){
Runnable task=queue.take();
task.run();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
}
}
}
public class Demo21 {
public static void main(String[] args) throws InterruptedException {
MyThreadPool threadPool=new MyThreadPool(10,20);
for (int i = 0; i < 10000; i++) {
int id=i;
threadPool.submit(new MyRunnable(){
@Override
public void run(){
System.out.println("hello"+id+","+Thread.currentThread());
}
});
}
}
}
定时器
package Thread;
import java.util.Timer;
import java.util.TimerTask;
//定时器
public class Demo22 {
public static void main(String[] args) {
Timer timer=new Timer();
//相当于run,继承了run
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 3000");
}
},3000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 2000");
}
},2000);
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello 1000");
}
},1000);
}
}
自制定时器
package Thread;
import java.util.PriorityQueue;
//自制定时器
//通过implements或者持有成员变量都是可以的
class MyTimerTask implements Comparable<MyTimerTask>{
private Runnable runnable;
//啥时候要去执行,此时的time不是delay,而是ms级别的时间戳(绝对时间)
private long time;
public MyTimerTask(Runnable runnable,long delay){
this.runnable=runnable;
//手动换算时间
this.time=System.currentTimeMillis()+delay;
}
public void run(){
runnable.run();
}
public long getTime(){
return time;
}
@Override
public int compareTo(MyTimerTask o){
//按照时间来进行比较,期望最终构造出的是小堆
return (int)(this.time-o.time);
}
}
class MyTimer{
private PriorityQueue<MyTimerTask> taskQueue=new PriorityQueue<>();
//也可以直接使用this作为锁对象
public MyTimer(){
//这个线程负责不断的扫描上述的队列队首元素,来确定是否要执行任务。。
Thread t=new Thread(() ->{
try{
synchronized (this){
while(true){
if(taskQueue.size()==0){
this.wait();
}
MyTimerTask task=taskQueue.peek();
long curTime=System.currentTimeMillis();
if(curTime>=task.getTime()){
//时间到了,要执行任务
task.run();
taskQueue.poll();
}else{
//时间没到
this.wait(task.getTime()-curTime);
}
}
}
} catch(InterruptedException e){
e.printStackTrace();
}
});
t.start();
}
public void schedule(Runnable runnable,long delay){
synchronized (this) {
MyTimerTask task = new MyTimerTask(runnable, delay);
taskQueue.offer(task);
this.notify();
}
}
}
public class Demo23 {
public static void main(String[] args) {
MyTimer myTimer=new MyTimer();
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 3000");
}
},3000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 2000");
}
},2000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello 1000");
}
},1000);
}
}
原文地址:https://blog.csdn.net/2302_80113478/article/details/143524580
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!