线程池

线程池

1. 线程池概念

 

2. 标准库线程池 (面试考点)

corePoolSize -> 核心线程数, 一个线程池创建出来, 就有这么多个核心线程, 相当于正式员工

maximumPoolSize -> 最多线程数 ( 核心线程数 +  非核心线程数 )

如果任务多了核心线程数处理不过来, 就会创建新的线程处理 (非核心线程, 数量最多 -> 最多线程数 - 核心线程数) 

等任务少了, 这些新创建出的非核心线程就回收了, 但是核心线程不变

 

 

keepAliveTime -> 允许非核心线程空闲的最大时间, 超过时间了就回收

unit -> 时间单位, 秒分小时

workQueue -> 线程池中, 保存执行任务的队列

threadFactory -> 创建线程的工厂类, 就是这个类中有静态方法可以直接创建对象

 

总结:

 

 

3. 工厂类创建线程池和基本使用

工厂类创建线程池 + 向线程池中添加任务 

 

查看代码
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Test {
    public static void main(String[] args) {
        // 1. 能够根据任务的数目, 自动进行线程扩容.
        // 可以会创建很多个线程, 系统负担大, 不好
        // ExecutorService service = Executors.newCachedThreadPool();

        // 2. 固定创建10个线程的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 10000; i++) {
            int id = i;
            // 往线程池里添加任务
            service.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

4. 自己实现线程池

1. 固定核心线程

查看代码
 import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class MyThreadPool {

    // 阻塞队列
    private  BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);

    // 初始化 创建固定线程的线程池 (FixedThreadPool)
    public MyThreadPool(int n) {
        for (int i = 0;i < n;i++) {
            Thread t = new Thread( () -> {
                try {
                    while (true) {
                        Runnable runnable = queue.take();
                        runnable.run();
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();
        }
    }

    // 把任务添加到线程池中
    public void submit(Runnable runnable) throws InterruptedException {
        queue.put(runnable);
    }

}

public class Main {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool threadPool = new MyThreadPool(10);
        for (int i = 0;i < 10000;i++) {
            // 往线程池里添加任务
            int id = i;
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

2. 核心线程 + 非核心线程 

查看代码
 

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

// 写一个比较简单的线程池.
class MyThreadPool {
    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) {
                    e.printStackTrace();
                }
            });
            t.start();
            threadList.add(t);
        }
    }

    // 把任务添加到线程池中
    void submit(Runnable runnable) throws InterruptedException {
        // 此处进行判定, 判定说当前任务队列的元素个数, 是否比较长.
        // 如果队列元素比较长, 说明已有的线程, 不太能处理过来了. 创建新的线程即可.
        // 如果队列不是很长, 没必要创建新的线程.
        queue.put(runnable);

        // 这里的 阈值 都是咱们拍脑门想的.
        while (queue.size() >= 500 && threadList.size() < maxPoolSize) {
            // 创建新的线程即可
            Thread t = new Thread(() -> {
                try {
                    while (true) {
                        Runnable task = queue.take();
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            t.start();
            threadList.add(t);
        }
    }
}

class Demo35 {
    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 Runnable() {
                @Override
                public void run() {
                    System.out.println("hello " + id + ", " + Thread.currentThread().getName());
                }
            });
        }
    }
}

 

 

5. 定时器

1. Java 库函数中定时器使用

查看代码
import java.util.Timer;
import java.util.TimerTask;

class Demo36 {
    public static void main(String[] args) {
        Timer timer = new Timer();

        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);
    }
}

 

2. 自己实现个定时器

查看代码
package demo2;

import java.util.Comparator;
import java.util.PriorityQueue;

class MyTimerTask implements Comparator<MyTimerTask>, Comparable<MyTimerTask> {

    private Runnable task;
    // 绝对时间
    private long time;

    public MyTimerTask(Runnable task,long delay) {
        this.task = task;
        this.time = System.currentTimeMillis() + delay;
    }

    public void run() {
        task.run();
    }

    public long getTime() {
        return time;
    }

    @Override
    public int compare(MyTimerTask o1, MyTimerTask o2) {
        return (int) (o1.time - o2.time);
    }

    @Override
    public int compareTo(MyTimerTask o) {
        return (int) (this.time - o.time);
    }
}

class MyTimer  {
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();
    private Object locker = new Object();

    public MyTimer() {
        Thread t = new Thread( () -> {
            try {
                while (true) {
                    synchronized (locker) {
                        if (queue.size() == 0) {
                            locker.wait();
                        }
                        MyTimerTask top = queue.peek();
                        // 时间到了, 执行任务
                        if (System.currentTimeMillis() >= top.getTime()) {
                            top.run();
                            queue.poll();
                        }else {
                            // 时间没到 -> 等待
                            locker.wait(top.getTime() - System.currentTimeMillis());
                        }
                    }
                }
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
    }

    // 往队列中添加任务
    public void schedule(Runnable task,long delay) {
        synchronized (locker) {
            MyTimerTask myTimerTask = new MyTimerTask(task,delay);
            queue.offer(myTimerTask);
            locker.notify();
        }
    }
}

class Test {
    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);

        System.out.println("===");
    }
}

 

posted @ 2024-04-28 11:13  qyx1  阅读(41)  评论(0)    收藏  举报