| 1、诸如 Web 服务器、数据库服务器、文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务。请求以某种方式到达服务器,这种方式可能是通过网络协议(例如 HTTP、FTP )、通过 JMS队列或者可能通过轮询数据库。不管请求如何到达,服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的。每当一个请求到达就创建一个新线程,然后在新线程中为请求服务,但是频繁的创建线程,销毁线程所带来的系统开销其实是非常大的 |
| 2、线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足 |
| 3、风险与机遇:用线程池构建的应用程序容易遭受任何其它多线程应用程序容易遭受的所有并发风险,诸如同步错误和死锁,它还容易遭受特定于线程池的少数其它风险,诸如与池有关的死锁、资源不足和线程泄漏 |
| public class ThreadPoolDemo { |
| |
| public static void main(String[] args) throws ExecutionException, InterruptedException { |
| |
| LinkedBlockingQueue<Runnable> objects = new LinkedBlockingQueue<>(10); |
| |
| ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 3L, |
| TimeUnit.SECONDS, objects); |
| Future<String> submit = null; |
| for (int i = 0; i < 100; i++) { |
| threadPoolExecutor.submit(()->{ |
| try { |
| Thread.sleep(2000L); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| System.out.println(Thread.currentThread().getName()); |
| }); |
| } |
| } |
| |
| } |
| |
| # 控制台打印结果: |
| pool-1-thread-10 |
| pool-1-thread-18 |
| pool-1-thread-7 |
| pool-1-thread-3 |
| pool-1-thread-8 |
| pool-1-thread-9 |
| pool-1-thread-2 |
| pool-1-thread-13 |
| pool-1-thread-20 |
| pool-1-thread-14 |
Future、Callable、FutureTask
| 1、Callable与Runable功能相似,Callable的call有返回值,可以返回给客户端,而Runable没有返回值,一般情况下,Callable与FutureTask一起使用,或者通过线程池的submit方法返回相应的Future |
| 2、Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果 |
| 3、FutureTask则是一个RunnableFuture,而RunnableFuture实现了Runnbale又实现了Futrue这两个接口 |
| import java.util.concurrent.Callable; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.FutureTask; |
| |
| public class CallableDemo implements Callable<String> { |
| |
| |
| @Override |
| public String call() throws Exception { |
| Thread.sleep(3000L); |
| return "1111"; |
| } |
| |
| |
| public static void main(String[] args) throws ExecutionException, InterruptedException { |
| |
| CallableDemo callableDemo = new CallableDemo(); |
| |
| FutureTask<String> stringFutureTask = new FutureTask<>(callableDemo); |
| |
| new Thread(stringFutureTask).start(); |
| |
| System.out.println(stringFutureTask.get()); |
| } |
| |
| } |
| public class ThreadPoolDemo { |
| |
| public static void main(String[] args) throws ExecutionException, InterruptedException { |
| |
| LinkedBlockingQueue<Runnable> objects = new LinkedBlockingQueue<>(); |
| |
| |
| ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 3L, |
| TimeUnit.SECONDS, objects); |
| |
| Future<String> submit = null; |
| |
| for (int i = 0; i < 100; i++) { |
| submit = threadPoolExecutor.submit(new CallableDemo()); |
| } |
| |
| for (int i = 0; i < 100; i++) { |
| System.out.println(submit.get()); |
| } |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
2021-05-16 真实机中安装CentOS7(一)