java线程池阿里_这份阿里技术官强推的java线程池笔记,建议你看一下,对工作太有帮助了...

线程池

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

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

因此线程池出现了

线程池的概念

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

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

避免频繁的创建和销毁

线程池的原理

66db6180cd32

获取线程池

66db6180cd32

创建线程池

public class TestThreadPool {

public static void main(String[] args) {

// 1. 创建固定线程个数的线程池对象

//线程池里可存在4个线程

ExecutorService es = Executors.newFixedThreadPool(4);

// 2. 创建任务

Runnable runnable = new Runnable() {

private int ticket = 100;

@Override

public void run() {

while (true) {

if(ticket <= 0) {

break;

}

System.out.println(Thread.currentThread().getName() + "买了" + ticket--);

}

}

};

// 3. 提交任务

for(int i = 0; i < 5; i++) {

es.submit(runnable);

}

// 4. 关闭线程池

es.shutdown();

}

}

执行结果

66db6180cd32

// 1. 创建单线程的线程池

ExecutorService es = Executors.newSingleThreadExecutor();

// 1. 创建缓冲线程池,线程的个数由任务来决定

ExecutorService es = Executors.newCachedThreadPool();

Callable接口

public interface Callable{

public V call() throws Exception;

}

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

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

Future接口

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

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

示例

使用Future和Callable接口

使用两个线程,并发计算1-50,51-100的和,再进行汇总

//示例

public class TestCallable {

public static void main(String[] args) throws Exception {

// 1.创建线程池对象

ExecutorService es = Executors.newFixedThreadPool(2);

// 2. 提交任务并得到Future对象,任务有Callable匿名对象来承担

Future future1 = es.submit(new Callable() {

@Override

public Integer call() throws Exception {

//完成1-50的加和运算并得到结果

System.out.println("start 1-50 count...");

int sum = 0;

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

sum += i;

}

return sum;

}

});

Future future2 = es.submit(new Callable() {

@Override

public Integer call() throws Exception {

//完成51-100的加和运算并得到结果

System.out.println("start 51 - 100 count...");

int sum = 0;

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

sum += i;

}

return sum;

}

});

// 3. 使用Future对象的get()方法得到运算结果

System.out.println("1-100的加和结果为:" + (future1.get() + future2.get()));

// 4. 关闭资源

es.shutdown();

}

}

结果

66db6180cd32

Lock接口

JDK5加入,与synchronized比较,显示定义,结构更灵活

提供更多实用性方法,功能更加强大,性能更优越

常用方法

//获取锁,如锁被占用,则等待

void lock()

//尝试获取锁(成功true,失败false,不阻塞)

boolean tryLock

//释放锁

void unlock()

//示例

public class TestLock implements Runnable {

Lock l = new ReentrantLock();

private int ticket = 100;

@Override

public void run() {

while (true) {

l.lock();

try {

if(ticket <= 0) {

break;

}

System.out.println(Thread.currentThread().getName() + " sells " + ticket--);

} catch (Exception e) {

e.printStackTrace();

}finally {

l.unlock();

}

}

}

public static void main(String[] args) {

ExecutorService es = Executors.newFixedThreadPool(4);

for(int i = 0; i < 4; i++) {

es.submit(new TestLock());

}

es.shutdown();

}

}

执行结果

66db6180cd32

线程安全的集合

66db6180cd32

Collections中的工具方法

66db6180cd32

Queue接口(队列)

66db6180cd32

//示例

public class TestQueue {

public static void main(String[] args) {

// 1. 创建PriorityQueue队列对象

PriorityQueue q = new PriorityQueue();

// 2. 队列添加元素,“入列”

q.offer("a");

q.offer("b");

q.offer("c");

q.offer("d");

q.offer("e");

// 3. 取值,“出列”

System.out.println(q.poll());

System.out.println(q.poll());

System.out.println(q.poll());

System.out.println(q.poll());

System.out.println(q.poll());

}

}

执行结果

66db6180cd32

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值