java 线程池存在的意义
前言
再次之前我已经花费大量篇幅介绍了Java原声锁和Lock锁。在文章中提到偏向送、轻量级锁、重量级锁、公平锁、非公平锁、自旋锁、自适应自旋锁、分布式锁、分段锁等等锁。所有的锁都是为了解决一个问题应运而生的那就是并发。而产生并发的原因是CPU的发展导致我们程序多线程运行。在代码中我们也经常通过多线程来提高产品的吞吐量。
在锁章节中我们也是通过多线程案例模拟锁的产生的。那么Java领域中有哪几种方式生成线程呢?容我慢慢道来
创建线程
继承Thread
创建线程的方式Java为我们提供了四种方式,首先是继承Thread 。复写run方法就可以了。
public class ExtendThread extends Thread{ private Integer index; public ExtendThread(Integer index) { this.index = index; } @Override public void run() { System.out.println("当前索引值:"+index); } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new ExtendThread(i).start(); } } }
实现Runnable接口
第二种方式就是实现Runnable接口。我们点进Thread源码也能看到,thread的构造需要一个Runnable接口。
public class TestRunnable implements Runnable{ private String userName; public TestRunnable(String userName) { this.userName = userName; } @SneakyThrows @Override public void run() { TimeUnit.SECONDS.sleep(1); System.out.println("当前名称:"+userName); } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(new TestRunnable(String.format("我是%s", i))).start(); } } }
实现Callable接口
除了上面两种还有一个接口实现。还有一个Callable他和Runnable的区别在于有返回值
public class TestCallable implements Callable { private int i; public TestCallable(int i) { this.i = i; } @Override public Object call() throws Exception { System.out.println(Thread.currentThread()+"我是"+i); return i; } public static void main(String[] args) throws ExecutionException, InterruptedException { final FutureTask futureTask = new FutureTask(new TestCallable(1)); for (int i = 0; i < 100; i++) { new Thread(new FutureTask(new TestCallable(i))).start(); } System.out.println(futureTask.get()); } }
线程池
上面三种应该算是线程创建的基本方式。为了提高性能减少线程的开辟与销毁,JDK提出了线程池的概念。线程池主要是在线程闲置后进行回收防止被JVM销毁。这样下次在来任务的时候就可以直接将闲置的线程提供给任务使用就可以了。线程池的创建默认有三种方式。这里我们使用其中一种,至于线程池我们后面会着重介绍。
public class TPools { public static void main(String[] args) { final ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 100; i++) { int finalI = i; executorService.execute(new Runnable() { @Override public void run() { System.out.println("@@@@@"+ finalI); } }); } } }
小结
本章节我们简单介绍了四种方式创建线程。使用上没有区别。需要注意Callable
接口是具有返回值的。这种方式其实我们可以用来确认线程是否执行了。然后就是线程池方式创建。从线程的角度四种方式创建出来的线程具有同等性质。不同的是线程池会对线程进行回收管理。关于他的回收策略JDK给我们提供了不同的默认策略。也支持我们自定义线程结构。
到此这篇关于java 线程池存在的意义的文章就介绍到这了,更多相关java 线程池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot使用@SpringBootTest注解开发单元测试教程
这篇文章主要介绍了SpringBoot使用@SpringBootTest注解开发单元测试教程,本文通过详细的案例过程来说明如何使用该项技术,需要的朋友可以参考下2021-06-06详解Spring系列之@ComponentScan自动扫描组件
这篇文章主要介绍了Spring @ComponentScan自动扫描组件使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-06-06彻底搞明白Spring中的自动装配和Autowired注解的使用
这篇文章主要介绍了彻底搞明白Spring中的自动装配和Autowired注解的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-03-03Spring Boot整合持久层之JdbcTemplate多数据源
持久层是JavaEE中访问数据库的核心操作,SpringBoot中对常见的持久层框架都提供了自动化配置,例如JdbcTemplate、JPA 等,MyBatis 的自动化配置则是MyBatis官方提供的。接下来分别向读者介绍Spring Boot整合这持久层技术中的整合JdbcTemplate2022-08-08
最新评论