一个线程start多次会怎样?
结果:会报错。报错如下:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:705)
at com.java4all.test4.Test1.main(Test1.java:13)
分析:
看Thread类的源码,分析一下原因:
1.start方法的源码:
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
//一个线程启动超过一次,是不合法的。
//特别的,一个线程一旦完成,就不会被重新start。
*
* @exception IllegalThreadStateException if the thread was already
* started.
//如果一个线程已经启动了,再调用start方法,会抛出:IllegalThreadStateException异常。
* @see #run()
* @see #stop()
*/
//同步方法
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
新线程的状态为0
*/
if (threadStatus != 0)
//如果线程状态不是0,会抛出IllegalThreadStateException异常。
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
//通知线程组这个线程即将要start,所以可以让它加入线程组,并且,线程组中的未启动线程数将会减少一个。
group.add(this);
boolean started = false;
try {
start0();//这个方法时个本地方法,native方法
started = true;//启动线程后设置标志位为true
} finally {
try {
if (!started) {
//如果标记为false,执行threadStartFailed方法,见下分析
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
2.start0方法源码:
//这是一个native方法
private native void start0();
下面几个方法是在ThreadGroup这个类中
1.threadStartFailed方法源码:
/**
* Notifies the group that the thread {@code t} has failed
* an attempt to start.
//通知线程组,这个线程启动失败
*
* <p> The state of this thread group is rolled back as if the
* attempt to start the thread has never occurred. The thread is again
* considered an unstarted member of the thread group, and a subsequent
* attempt to start the thread is permitted.
*
//线程组的状态将会回滚到就像从未启动过此线程一样的状态。
这个线程将会被当做未启动的线程存在于线程组中,并且允许后面的线程开始start
* @param t
* the Thread whose start method was invoked
*/
void threadStartFailed(Thread t) {
synchronized(this) {//同步方法
remove(t);//从线程组中移除此线程
nUnstartedThreads++;//未启动线程数+1
}
}
2.remove方法源码:
/**
* Removes the specified Thread from this group. Invoking this method
* on a thread group that has been destroyed has no effect.
//从线程组中移除指定线程,在已经被销毁的线程池中执行此方法是没有效果的。
*
* @param t
* the Thread to be removed
*/
private void remove(Thread t) {
synchronized (this) {//同步
if (destroyed) {
return;
}
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
// Zap dangling reference to the dead thread so that
// the garbage collector will collect it.
//悬摆指针(不知道怎么翻译)指向这个死线程,这样垃圾回收机就可以回收这个了。
threads[nthreads] = null;
break;
}
}
}
}
3.add方法源码
/**
* Adds the specified thread to this thread group.
//制定的线程添加到线程组中。
*
* <p> Note: This method is called from both library code
* and the Virtual Machine. It is called from VM to add
* certain system threads to the system thread group.
*
* @param t
* the Thread to be added
*
* @throws IllegalThreadStateException
* if the Thread group has been destroyed
*/
void add(Thread t) {
synchronized (this) {
if (destroyed) {
//如果线程组被销毁,会抛出IllegalThreadStateException错误
throw new IllegalThreadStateException();
}
if (threads == null) {
//线程组为null时,新建一个
threads = new Thread[4];
} else if (nthreads == threads.length) {
//如果线程组的大小和线程数量相等,那就把线程组扩容到线程数量的2倍
threads = Arrays.copyOf(threads, nthreads * 2);
}
//把此线程赋值到线程组中
threads[nthreads] = t;
// This is done last so it doesn't matter in case the
// thread is killed
//线程数量+1
nthreads++;
// The thread is now a fully fledged member of the group, even
// though it may, or may not, have been started yet. It will prevent
// the group from being destroyed so the unstarted Threads count is
// decremented.
//未start线程数量-1
nUnstartedThreads--;
}
}