- 浏览: 1090493 次
文章分类
- 全部博客 (379)
- S2SH (16)
- stuts2 (0)
- java语言 (81)
- JSP (17)
- <html>元素 (11)
- javaweb (4)
- web容器 (3)
- ext (23)
- javaScript (48)
- ant (1)
- liferay (1)
- sql (9)
- css (42)
- 浏览器设置 (3)
- office_world (1)
- eclipse (4)
- 其它 (28)
- 操作系统 (5)
- android (6)
- Struts2 (11)
- RegEx (3)
- mysql (5)
- BigDATA (1)
- Node.js (1)
- Algorithm (10)
- Apache Spark (1)
- 数据库 (5)
- linux (2)
- git (1)
- Adobe (3)
- java语言,WebSocket (1)
- Maven (3)
- SHELL (1)
- XML (2)
- 数学 (2)
- Python (2)
- Java_mysql (1)
- ReactJS (6)
- 养生 (4)
- Docker (1)
- Protocols (3)
- java8 (2)
- 书籍 (1)
- Gradle (2)
- AngularJS (5)
- SpringMVC (2)
- SOAP (1)
- BootstrapCSS (1)
- HTTP协议 (1)
- OAuth2 (1)
最新评论
-
Lixh1986:
Java并发编程:自己动手写一把可重入锁https://blo ...
Java之多线程之Lock与Condition -
Lixh1986:
http://win.51apps.com.cn/https: ...
temp -
ztwsl:
不错,支持很好
HttpServletRequest和ServletRequest的区别 -
guodongkai:
谢谢您能将知识精华汇编总结,让初学者们从原理中学会和提高。
javaScript之function定义 -
kangwen23:
谢谢了,顶顶
struts2中的ValueStack学习
一、问题背景
在使用多线程时,如果要开启一个任务,则就需要新建一个线程。
线程也是对象,那么是否可以不用新建,而使用原来的呢?
试试下面的方法:
结果报错了:
Exception in thread "main" java.lang.IllegalThreadStateException
原因:
线程在执行完 start() 方法后,就会自动销毁。
二、如何解决线程重用
1、分析
每一个 Thread 的类都有一个 start 方法。
Thread 的 start 方法是这样描述的:
Causes this thread to begin execution;
the Java Virtual Machine calls the run method of this thread.
启动线程。Java虚拟机会调用该类的 run 方法。
那么该类的 run() 方法中就是调用了 Runnable 对象的 run() 方法。
2、解决
我们可以继承重写 Thread 类,在其 start 方法中添加不断循环调用传递过来的 Runnable 对象。
这就是线程池的实现原理。循环方法中不断获取 Runnable 是用 Queue 实现的,在获取下一个 Runnable 之前可以是阻塞的。
三、问题出处
Question: java thread reuse
I have always read that creating threads is expensive. I also know that you cannot rerun a thread.
I see in the doc of Executors class: Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
Mind the word 'reuse'.
How do thread pools 'reuse' threads?
------------
Answer:
I think I understood what is confuzzabling you so here's my longer answer: the terminology is a tiny bit misleading (obviously, or you wouldn't ask that question specifically putting the emphasis on 'reuse'):
How do thread pools 'reuse' threads?
What is happening is that a single thread can be used to process several tasks (typically passed as Runnable, but this depend on your 'executor' framework: the default executors accepts Runnable, but you could write your own "executor" / thread-pool accepting something more complex than a Runnable [like, say, a CancellableRunnable]).
Now in the default ExecutorService implementation if a thread is somehow terminated while still in use, it is automatically replaced with a new thread, but this is not the 'reuse' they're talking about. There is no "reuse" in this case.
So it is true that you cannot call start() on a Java Thread twice but you can pass as many Runnable as you want to an executor and each Runnable's run() method shall be called once.
You can pass 30 Runnable to 5 Java Thread and each worker thread may be calling, for example, run() 6 times (practically there's not guarantee that you'll be executing exactly 6 Runnable per Thread but that is a detail).
In this example start() would have been called 6 times. Each one these 6 start() will call exactly once the run() method of each Thread:
From Thread.start() Javadoc:
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
BUT then inside each Thread's run() method Runnable shall be dequeued and the run() method of each Runnable is going to be called. So each thread can process several Runnable. That's what they refer to by "thread reuse".
One way to do your own thread pool is to use a blocking queue on to which you enqueue runnables and have each of your thread, once it's done processing the run() method of a Runnable, dequeue the next Runnable (or block) and run its run() method, then rinse and repeat.
I guess part of the confusion (and it is a bit confusing) comes from the fact that a Thread takes a Runnable and upon calling start() the Runnable 's run() method is called while the default thread pools also take Runnable.
-
Thread pool threads are basically running loops that pull submitted tasks off of a queue. The threads do not stop executing when they service a task, they just wait for the next one to be submitted to the queue. They never get 'rerun' as asked in the question, as they are just constantly running.
-
The run method of threads in a thread pool does not consist only of running a single task.
The run method of a thread in a thread pool contains a loop.
It pulls a task off of a queue, executes the task (which returns back to the loop when it is complete), and then gets the next task.
The run method doesn't complete until the thread is no longer needed.
Here is the run method of the Worker inner class in ThreadPoolExecutor.
-
It's not actually unnecessary - the (strange) test for task!=null in the loop makes it necessary to prevent continually processing the same task. Even if the loop were more conventional nulling task would be good because otherwise if getTask() blocks for a long time, the GC of task would otherwise be delayed for the same length of time.
-
-
http://stackoverflow.com/questions/2324030/java-thread-reuse
在使用多线程时,如果要开启一个任务,则就需要新建一个线程。
线程也是对象,那么是否可以不用新建,而使用原来的呢?
试试下面的方法:
Thread incT = new Thread(new Inc(c)); Thread decT = new Thread(new Dec(c)); for(int i= 0; i < 200; i++){ incT.start(); System.out.println("incT:" + incT.getName()); decT.start(); System.out.println("decT:" + decT.getName()); }
结果报错了:
Exception in thread "main" java.lang.IllegalThreadStateException
原因:
线程在执行完 start() 方法后,就会自动销毁。
二、如何解决线程重用
1、分析
每一个 Thread 的类都有一个 start 方法。
Thread 的 start 方法是这样描述的:
Causes this thread to begin execution;
the Java Virtual Machine calls the run method of this thread.
启动线程。Java虚拟机会调用该类的 run 方法。
那么该类的 run() 方法中就是调用了 Runnable 对象的 run() 方法。
2、解决
我们可以继承重写 Thread 类,在其 start 方法中添加不断循环调用传递过来的 Runnable 对象。
这就是线程池的实现原理。循环方法中不断获取 Runnable 是用 Queue 实现的,在获取下一个 Runnable 之前可以是阻塞的。
三、问题出处
Question: java thread reuse
I have always read that creating threads is expensive. I also know that you cannot rerun a thread.
I see in the doc of Executors class: Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available.
Mind the word 'reuse'.
How do thread pools 'reuse' threads?
------------
Answer:
I think I understood what is confuzzabling you so here's my longer answer: the terminology is a tiny bit misleading (obviously, or you wouldn't ask that question specifically putting the emphasis on 'reuse'):
How do thread pools 'reuse' threads?
What is happening is that a single thread can be used to process several tasks (typically passed as Runnable, but this depend on your 'executor' framework: the default executors accepts Runnable, but you could write your own "executor" / thread-pool accepting something more complex than a Runnable [like, say, a CancellableRunnable]).
Now in the default ExecutorService implementation if a thread is somehow terminated while still in use, it is automatically replaced with a new thread, but this is not the 'reuse' they're talking about. There is no "reuse" in this case.
So it is true that you cannot call start() on a Java Thread twice but you can pass as many Runnable as you want to an executor and each Runnable's run() method shall be called once.
You can pass 30 Runnable to 5 Java Thread and each worker thread may be calling, for example, run() 6 times (practically there's not guarantee that you'll be executing exactly 6 Runnable per Thread but that is a detail).
In this example start() would have been called 6 times. Each one these 6 start() will call exactly once the run() method of each Thread:
From Thread.start() Javadoc:
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
BUT then inside each Thread's run() method Runnable shall be dequeued and the run() method of each Runnable is going to be called. So each thread can process several Runnable. That's what they refer to by "thread reuse".
One way to do your own thread pool is to use a blocking queue on to which you enqueue runnables and have each of your thread, once it's done processing the run() method of a Runnable, dequeue the next Runnable (or block) and run its run() method, then rinse and repeat.
I guess part of the confusion (and it is a bit confusing) comes from the fact that a Thread takes a Runnable and upon calling start() the Runnable 's run() method is called while the default thread pools also take Runnable.
-
Thread pool threads are basically running loops that pull submitted tasks off of a queue. The threads do not stop executing when they service a task, they just wait for the next one to be submitted to the queue. They never get 'rerun' as asked in the question, as they are just constantly running.
-
The run method of threads in a thread pool does not consist only of running a single task.
The run method of a thread in a thread pool contains a loop.
It pulls a task off of a queue, executes the task (which returns back to the loop when it is complete), and then gets the next task.
The run method doesn't complete until the thread is no longer needed.
Here is the run method of the Worker inner class in ThreadPoolExecutor.
696: /** 697: * Main run loop 698: */ 699: public void run() { 700: try { 701: Runnable task = firstTask; 702: firstTask = null; 703: while (task != null || (task = getTask()) != null) { 704: runTask(task); 705: task = null; // unnecessary but can help GC 706: } 707: } finally { 708: workerDone(this); 709: } 710: }
-
It's not actually unnecessary - the (strange) test for task!=null in the loop makes it necessary to prevent continually processing the same task. Even if the loop were more conventional nulling task would be good because otherwise if getTask() blocks for a long time, the GC of task would otherwise be delayed for the same length of time.
-
-
http://stackoverflow.com/questions/2324030/java-thread-reuse
发表评论
-
java 将文件夹所有的文件合并到指定的文件夹下
2020-06-30 19:17 974场景:将文件夹所有的文件合并到指定的文件夹下 另外:如果想效 ... -
多线程-线程池的四种创建方式
2020-04-01 18:38 407多线程-线程池的四种创建方式 https://blog.cs ... -
Java基础之:nio
2019-11-13 15:38 410一、理论讲解: 史上最强Java NIO入门:担心从入门到放弃 ... -
Java 分布式之:RPC 基本概念
2019-11-13 15:07 398转载: https://www.jianshu.com/p/ ... -
Java之 volatile 关键字原理详解
2019-11-07 15:36 439一、什么是 volatile ? ... -
POI实现excell批注背景图片(仿html浮窗显示图片)
2019-10-21 08:17 597POI实现excell批注背景图片(仿html浮窗显示图片) ... -
Java之设计模式之 Observer 观察者
2019-07-04 17:21 970观察者设计模式 Java 已经实现了该模式,并且提供了使用类 ... -
HashMap, LinkedHashMap and TreeMap
2019-03-01 11:04 623https://stackoverflow.com/a/177 ... -
Java lib 操作 excel 插入图片
2019-01-19 12:46 837https://poi.apache.org/componen ... -
数据库连接池C3P0
2018-05-29 16:50 809一、名字的由来 很多 ... -
Java8之集合(Collection)遍历 forEach()、stream()
2018-05-29 14:39 20656package java8.collections; ... -
Junit Vs main on "java.util.concurrent.Executors"
2017-11-10 16:44 731Same code with different result ... -
Java之大数据学习路线
2017-11-03 10:08 5672三个月大数据研发学习 ... -
Java中创建对象的5种方式
2017-10-26 14:21 803一、Java之5种创建对象的方式 ————————————— ... -
Log4j和Slf4j的比较
2017-06-23 12:41 1358一直搞不清 Log4j 和 SLF4j 的关系。今天才若有所 ... -
Java之Java7新特性之try资源句式
2017-04-20 14:58 5337Java之Java7新特性之try资源句式 一、【try资源 ... -
Java之 java.util.concurrent 包之ExecutorService之submit () 之 Future
2017-03-04 21:27 3770一、如何使用 ExecutorService.submit() ... -
Java之 java.util.concurrent 包之Executor与ExecutorService
2017-03-04 21:18 2639一、问题: execute() 与 submit() 的区别? ... -
JAVAEE之单用户登录
2017-02-05 11:55 1031单用户登录是系统中数据一直性的解决方案之一。 问题背景: 试 ... -
Java之语法之方法调用之地址传值之空对象(null)
2017-01-26 14:05 3232一、问题: public void test ...
相关推荐
java多线程,对多线程,线程池进行封装,方便使用
java多线程并发查询数据库,使用线程池控制分页,并发查询。
* 使用多线程的好处: 1.降低消耗,减少了创建和销毁线程的次数,每个线程都可以重复利用,可执行多个任务 2.提高响应速度,任务可以不需要等到线程创建就可以立即执行 3.提高线程的可管理性,根据系统的承受能力,...
JAVA使用线程池查询大批量数据
Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...
Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多...
java线程、线程池、xml解析 适合入门的例子或文档 上手使用
用于数据量大的情况下预先查询出数据,加快对后面页面数据的查询速度
Java多线程(Synchronized+Volatile+JUC 并发工具原理+线程状态+CAS+线程池)
这个是关于Java多线程方面的技术,就是多个线程发送请求,从互联网上下载图片资源,通过这个案例可以知道Java中的多线程的基础知识
刚学完多线程和线程池,以及线程爱好者。 使用场景及目标: 大文件的快速下载,经测试在100M带宽的网络下,下载一个40M的文件,不超过两秒钟,当然还得根据自己电脑的配置来讲。 其他说明: 文件如果特别小,而...
Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java线程:新特征-信号量 Java线程:新特征-阻塞队列 Java线程:新特征-阻塞栈 Java线程:...
详细的讲述了多线程的各种用法 Java线程:概念与原理 Java线程:创建与启动 Java线程:线程栈模型与线程的变量 Java线程:线程状态的转换 Java线程:线程的同步与锁 Java线程:线程的交互 Java线程:线程的调度-休眠...
java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
重复利用已经创建的线程,减少创建线程和销毁线程的开销 提高响应速度,不需要等到线程创建就能立即执行 使用线程池可以进行统一分配,调优和监控 总的来说:降低资源消耗,提高响应速度,提高线程可管理性
里面是自己收藏的几篇关于线程的文档资料,大家可以看看哈
目标:Java中多线程技术是一个难点,但是也是一个核心技术。因为Java本身就是一个多线程语言。本人目前在给46班讲授Swing的网络编程--使用Swing来模拟真实的QQ实时聊天软件。因为涉及到Socket编程,所以一定会使用多...
1. SpringBoot 自定义线程池以及多线程间的异步调用(@Async、@EnableAsync) 2.Java多线程之定时任务 以及 SpringBoot多线程实现定时任务 3.@EnableScheduling 与 @Scheduled