Java using the default thread pool trampled pits (ii)

Source: Internet
Author: User

Yun Zhihui (Beijing) Technology Co., Ltd. Chenxin

Yes. A thread cannot be started two times. So how does it come to be inferred?
Public synchronized void Start () {
* A Zero status valuecorresponds to State "NEW". 0 The corresponding is state NEW
if (threadstatus!= 0)//Assuming it is not new state, throw an exception directly!
Throw Newillegalthreadstateexception ();
Group.add (this);
Boolean started = false;
try {
Start0 (); Native methods for starting threads
started = true;
} finally {
try {
if (!started) {
Group.threadstartfailed (this);
} catch (Throwable ignore) {
Well, only the new state can invoke the native method to start a thread. All right. Got here. In popularity also self-complements the thread state in the JVM:
Full thread state::
L new--hasn't started yet.
L runnable--is executing on the JVM.
L blocked--is waiting for the lock/semaphore to be released
L waiting--wait for a specific action on one of the other threads
L TIMED_WAITING--A Thread, iswaiting for another, thread to perform an action for up to A specified waitingtime are in This state.
L terminated--exit, stop
A thread may have only one state at a point in time. These states are in the JVM and do not reflect the state of the operating system threads. Check the thread API and there is no API to change its state. So this is a way out of line?
Take a careful look at ...
Assume that the task is made into a runnable implementation class, and then, before throwing the implementation class into the thread pool scheduler, use this runnable to construct a thread that is not the thread object that controls this Runnable object. And then control the task that executes in the thread pool? Not too! Let's take a look at thread and Threadpoolexecutor to runnable.
/* What would berun. */
Private Runnabletarget;
In combination with the start () method above, it is very easy to guess that start0 () will make the target into a thread for execution.

public void execute (Runnable command) {
if (command== null)
Thrownew Nullpointere Xception ();
int c =ctl.get ();
if (Workercountof (c) < corepoolsize) {
if (addworker (command, True))
C =ctl.get ();
if (IsRunning (c) && workqueue.offer (command)) {
Intrecheck = Ctl.get ();
if (!isrunning (recheck) && Remove (command))
Reject (command);
Else if (workercountof (recheck) = = 0)
Addworker (null, FALSE);
Else if (!addworker (command, false))
Reject (command);

Private Boolean Addworker (Runnablefirsttask, Boolean core) {
booleanworkerstarted = false;
booleanworkeradded = false;
Worker W =null;
try {
Finalreentrantlock mainlock = This.mainlock;
W = Newworker (firsttask);
Finalthread t = w.thread;
if (t!= null) {
Mainlock.lock ();
int c = Ctl.get ();
int rs = runstateof (c);

               if (rs < SHUTDOWN ||                   (rs == SHUTDOWN && firstTask == null)) {                   if (t.isAlive()) // precheck that t is startable                        throw newIllegalThreadStateException();

Workers.add (w);
int s = workers.size ();
if (S > Largestpoolsize)
Largestpoolsize =s;
Workeradded = true;
}finally {
Mainlock.unlock ();
if (workeradded) {
T.start ();
Workerstarted = true;
} finally {
if (!workerstarted)
Addworkerfailed (w);
return workerstarted;
So what about the worker?
Private Final Class Worker
Finalthread thread;
Volatilelong Completedtasks;
Worker (Runnable firsttask) {
SetState (-1); You cannot interrupt before calling Runworker
This.firsttask = Firsttask;
This.thread = Getthreadfactory (). Newthread (this);
Public Voidrun () {
Runworker (this);
Voidinterruptifstarted () {
if (getState () >= 0 && (t = thread)! = null &&!t.isinterrupted ()) {
T.interrupt ();
}catch (SecurityException ignore) {
It is visible that the worker has both wrapped the Runnable object--task and wrapped a thread object--as an initialization parameter. Because the worker is also a Runnable object.

It then provides external execution and stop interfaces, run () and interruptifstarted (). Recall that the sample using thread above could not help but have a new understanding, we put a thread object to threadpoolexecutor after execution. The actual call is to the thread (Filetask ()) object, which we temporarily call Workerwrapper.

So our filetask.interrupt () operation outside the pool affects the Filetask object. Rather than workerwrapper. So it may not be particularly appropriate to call the start () method two times above. It should be more appropriate to run out of the Filetask.interrupt (), since the start () method has never been performed on the Filetask object. There will be errors when you go to interrupt. In detail for example with:

In this analysis, we have learned that there is no other way to manipulate these workers except for the Interruptworkers () method called Threadpoolexecutor.
private void Interruptworkers () {
Finalreentrantlock mainlock = This.mainlock;
Mainlock.lock ();
try {
for (Worker w:workers)
W.interruptifstarted ();
} finally {
Mainlock.unlock ();

Java using the default thread pool trampled pits (ii)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.