线程池(重要)

标准库中的线程池

使⽤ Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.
返回值类型为 ExecutorService
通过 ExecutorService.submit 可以注册⼀个任务到线程池中
ExecutorService pool = Executors.newFixedThreadPool( 10 );
pool.submit( new Runnable () {
@Override
public void run () {
System.out.println( "hello" );
}
});

Executors 创建线程池的⼏种⽅式

newFixedThreadPool: 创建固定线程数的线程池
newCachedThreadPool: 创建线程数⽬动态增⻓的线程池.
newSingleThreadExecutor: 创建只包含单个线程的线程池.
newScheduledThreadPool: 设定 延迟时间后执⾏命令,或者定期执⾏命令. 是进阶版的 Timer.
Executors 本质上是 ThreadPoolExecutor 类的封装
面试问题

ThreadPoolExecutor 提供了更多的可选参数, 可以进⼀步细化线程池⾏为的设定.

corePoolSize: 正式员⼯的数量. (正式员⼯, ⼀旦录⽤, 永不辞退)
maximumPoolSize: 正式员⼯ + 临时⼯的数⽬. (临时⼯: ⼀段时间不⼲活, 就被辞退).
keepAliveTime: 临时⼯允许的空闲时间.
unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值.
workQueue: 传递任务的阻塞队列
(重要 )threadFactory: 创建线程的⼯⼚, 参与具体的创建线程⼯作. 通过不同线程⼯⼚创建出的线程相当于
对⼀些属性进⾏了不同的初始化设置.
1.RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理.
2.AbortPolicy(): 超过负荷, 直接抛出异常.
3.CallerRunsPolicy(): 调⽤者负责处理多出来的任务.
4.DiscardOldestPolicy(): 丢弃队列中最⽼的任务.
5.DiscardPolicy(): 丢弃新来的任务.

实现线程池

核⼼操作为 submit, 将任务加⼊线程池中
使⽤ Worker 类描述⼀个⼯作线程. 使⽤ Runnable 描述⼀个任务.
使⽤⼀个 BlockingQueue 组织所有的任务
每个 worker 线程要做的事情: 不停的从 BlockingQueue 中取任务并执⾏.
指定⼀下线程池中的最⼤线程数 maxWorkerCount; 当当前线程数超过这个最⼤值时, 就不再新增
线程
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class MyThreadpool{
    private BlockingQueue<Runnable> queue=null;/使⽤⼀个 BlockingQueue 组织所有的任务

   //// 创建了⼀个固定数量的线程池
    public MyThreadpool(int n){

//ArrayBlockingQueue为任务队列,容量为1000
        queue=new ArrayBlockingQueue<>(1000);
        while(n>0){
            Thread t=new Thread(()->{
                while (true){
                    try {
                        Runnable arr=queue.take();//使⽤ Runnable 描述⼀个任务. 
                        arr.run();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
            t.start();
            n--;
        }
    }
                      //使⽤ Runnable 描述⼀个任务.
    public void submit(Runnable stak) throws InterruptedException {/核⼼操作为 submit, 将任务加⼊线程池中
        queue.put(stak);
    }
}
//线程池
public class work2 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadpool per=new MyThreadpool(10);
        int i=0;
        for( i=0;i<100;i++){
            int id=i;
            per.submit(()->{
                System.out.println(Thread.currentThread().getName()+" id "+id);
            });
        }
    }
}

 对⽐线程和进程

 线程的优点

1. 创建⼀个新线程的代价要⽐创建⼀个新进程⼩得多
2. 与进程之间的切换相⽐,线程之间的切换需要操作系统做的⼯作要少很多
3. 线程占⽤的资源要⽐进程少很多
4. 能充分利⽤多处理器的可并⾏数量
5. 在等待慢速I/O操作结束的同时,程序可执⾏其他的计算任务
6. 计算密集型应⽤,为了能在多处理器系统上运⾏,将计算分解到多个线程中实现
7. I/O密集型应⽤,为了提⾼性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。

进程与线程的区别

1. 进程是系统进⾏资源分配和调度的⼀个独⽴单位,线程是程序执⾏的最⼩单位。
2. 进程有⾃⼰的内存地址空间,线程只独享指令流执⾏的必要资源,如寄存器和栈。
3. 由于同⼀进程的各线程间共享内存和⽂件资源,可以不通过内核进⾏直接通信。
4. 线程的创建、切换及终⽌效率更⾼。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值