java 线程池实现类_Java线程池的创建和线程池接口和实现类详解

1. 线程池概念

现有问题:

线程是宝贵的内存资源、单个线程约占1MB的空间,过多分配易造成内存溢出;

频繁的创建及销毁会增加虚拟机回收频率、资源开销,造成程序性能下降。

线程池:

线程容器,可设定线程分配的数量上限;

将预先创建的线程对象存入池中,并重用线程池中的线程对象;

避免频繁的创建和销毁。

2. 线程池原理

将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。

db01e8940390

Java线程池

3. 获取线程池 - Executor接口 & Executors工具类

常用的线程池接口和类:

① Executor // 接口,线程池的顶级接口

② ExecutorService //接口,线程池接口,可通过Future> submit(Runnable task)提交任务代码

③ Executors // 工厂类,通过此类可以获得一个线程池

(1)通过 Executors.newFixedThreadPool(int nThreads) 获取固定数量的线程池

@nThreads int 指定线程池中线程的数量

@return ExecutorService 接口类型引用

(2)通过 Executors.newCachedThreadPool()获得动态数量的线程池,如不够则创建新的,没有上限

@return ExecutorService 接口类型引用

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class TestThreadPool {

public static void main(String[] args) {

// 线程池引用 --> 指向Executors工具类(工厂类)

// 手动限定线程池中的固定数量

//ExecutorService es = Executors.newFixedThreadPool(3);

// 动态数量的线程池

ExecutorService es = Executors.newCachedThreadPool();

// 1.创建任务类对象

MyTask task = new MyTask();

// 2.将任务提交到线程池,由线程池调度、执行(谁先运行结束则优先被复用)

es.submit(task);

es.submit(task);

es.submit(task);

es.submit(task);

es.submit(task);

es.submit(task);

}

}

// 线程任务

class MyTask implements Runnable {

public void run() {

int i = 0;

while (i++ < 10) {

System.out.println(Thread.currentThread().getName() + ":" + i);

}

}

}

4. Callable接口

public interface Callable {

public V call() throws Exception;

}

特点:

JDK5加入,与Runnable接口类似,实现之后代表一个线程任务;

Callable具有泛型返回值,可以声明异常。

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class TestCallable {

public static void main(String[] args) {

ExecutorService es = Executors.newFixedThreadPool(3);

ThisTask task = new ThisTask();

es.submit(task);

}

}

class ThisTask implements Callable {

@Override

public Object call() throws Exception {

for (int i = 1; i <= 50; i++) {

Thread.sleep((int)(Math.random() * 1000));

System.out.println(Thread.currentThread().getName() + ":" + i);

}

return null;

}

}

5. Future接口

public interface Future

特点:

异步接收ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值;

方法:V get()以阻塞形式等待Future中的异步处理结果(call()的返回值)

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

public class TestFuture {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService es = Executors.newFixedThreadPool(3);

MyCall call = new MyCall();

MyCall2 call2 = new MyCall2();

// 通过submit执行提交的任务,Future接收返回的结果

Future f = es.submit(call);

Future f2 = es.submit(call2);

System.out.println( f.get() + f2.get()); // 5050

}

}

// 计算1~50的和

class MyCall implements Callable {

@Override

public Integer call() throws Exception {

Integer sum = 0;

for (int i = 1; i <= 50; i++) {

sum += i;

}

System.out.println(Thread.currentThread().getName() + ":" + sum);

return sum; // 1275

}

}

// 计算51~100的和

class MyCall2 implements Callable {

@Override

public Integer call() throws Exception {

Integer sum = 0;

for (int i = 51; i <= 100; i++) {

sum += i;

}

System.out.println(Thread.currentThread().getName() + ":" + sum);

return sum; // 3775

}

}

6. 线程的异步与同步

同步:

形容一次方法调用,同步一旦开始,调用者必须等待该方法返回,才能继续。

同步为单条执行路径。

异步:

形容一次方法调用,异步一旦开始,像是一次消息传递,调用者告知之后立刻返回,二者竞争时间片,并发执行。

异步为多条执行路径。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值