自学内容网 自学内容网

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)!