Thread的方法有很多,但是经过JDK版本的迭代与bug的修复,使得它的方法逐步完善,也使得一些方法逐渐过时,并被标识为不推荐使用,接下来我们就一起看下Thread的方法的使用:
一.run() 与start()方法的区别
run() 是Thread的一个普通的方法,调用该方法并不会开启线程;
start() 方法被调用的时候,Thread将会调用jdk底层的C语言开启一个线程;
start() 方法只能被同一个线程调用一次,调用第二次时会报错,而run()不会;
二. Thread的常用方法
1.interrupt()方法:中断提示标识符,不会真的中断线程只是修改中断标识位
Jdk解释说明:
* Interrupts this thread.
*
* <p> Unless the current thread is interrupting itself, which is
* always permitted, the {@link #checkAccess() checkAccess} method
* of this thread is invoked, which may cause a {@link
* SecurityException} to be thrown.
中断线程:除非当前线程正在中断,那也是被允许的,checkAccess()方法将被当前当前线程调用,这
可能会抛出SecurityException
* <p> If this thread is blocked in an invocation of the {@link
* Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
* Object#wait(long, int) wait(long, int)} methods of the {@link Object}
* class, or of the {@link #join()}, {@link #join(long)}, {@link
* #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
* methods of this class, then its interrupt status will be cleared and it
* will receive an {@link InterruptedException}.
如果当前线程被Object类的wait(),wait(long),wait(long,int)或被当前类join(long,int),
sleep(long)方法调用阻塞,那么线程的中断状态将被清除并抛出InterruptedException
<p> If this thread is blocked in an I/O operation upon an {@link
* java.nio.channels.InterruptibleChannel InterruptibleChannel}
* then the channel will be closed, the thread's interrupt
* status will be set, and the thread will receive a {@link
* java.nio.channels.ClosedByInterruptException}.
* 如果此线程在上的I / O操作中被阻塞,则该通道将被关闭,线程的中断状态将被设置,并且该
* 线程将收到一个ClosedByInterruptException
*
* <p> If this thread is blocked in a {@link java.nio.channels.Selector}
* then the thread's interrupt status will be set and it will return
* immediately from the selection operation, possibly with a non-zero
* value, just as if the selector's {@link
* java.nio.channels.Selector#wakeup wakeup} method were invoked.
* 如果此线程在java.nio.channels.Selector中被阻塞,则将设置该线程的中断状态,并且它
* 将立即从选择操作中返回,可能具有非零值,就像选择器的java.nio.channels.Selector#wakeup
* 唤醒}方法已被调用。
* <p> If none of the previous conditions hold then this thread's interrupt
* status will be set. </p>
* 如果没有先前的条件发生,则线程的中断状态将被设置。
* <p> Interrupting a thread that is not alive need not have any effect.
* 中断未激活的线程不会产生任何效果。
a. 测试异常,中断状态改变
private static class ThreadOne extends Thread{
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " start isInterrupted :" +isInterrupted());
try {
Thread.sleep(10);
} catch (Exception e) {
System.out.println(name + " end isInterrupted :" +isInterrupted());
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadOne threadOne = new ThreadOne();
threadOne.start();
//中断标识 默认为false, 标识中断(interrupt())后 值修改为true
threadOne.interrupt();
System.out.println("main方法结束。。。。");
}
执行结果:
线程的中断标识位被置为true,再调用sleep()方法时:线程中断状态改变,抛出异常。
反之,线程先休眠,在休眠的过程中,中断标识位被改变,也将抛出异常。
b. 测试interrupt()只是修改了中断状态没有去中断线程
public static void main(String[] args) throws InterruptedException {
ThreadTwo threadTwo = new ThreadTwo();
threadTwo.start();
//中断标识 默认为false, 标识中断(interrupt())后 值修改为true
threadTwo.interrupt();
System.out.println("main方法结束。。。。");
}
private static class ThreadTwo extends Thread{
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " start isInterrupted :" +isInterrupted());
while (true){
System.out.println("子线程:is running 。。。。");
}
}
}
执行结果:线程一直执行,不会中断
总结:从这么长的注释上可以获知这个方法只是改变了这个线程的中断状态,并且在第二段的说明中:在另外的几个方法的调用时中断状态将被清除,并抛出一个异常!
2.interrupted()方法和isInterrupted()
Jdk解释说明:
interrupted():Tests whether the current thread has been interrupted. The <i>
interrupted status</i>of the thread is cleared by this method
测试当前线程是否被中断,这个方法会清除线程的中断状态。
isInterrupted():Tests whether this thread has been interrupted. The <i>interrupted
status</i> of the thread is unaffected by this method.
测试当前线程是否被中断,这个方法不会清除线程的中断状态。
a.测试线程中断状态被清除
public static class ThreadOne extends Thread {
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " start isInterrupted :" +isInterrupted());
System.out.println(name + " start2 isInterrupted :" +isInterrupted());
while (!Thread.interrupted()){
System.out.println("子线程:is running 。。。。");
}
System.out.println(name + " end isInterrupted :" +isInterrupted());
}
}
public static void main(String[] args) {
ThreadOne threadOne = new ThreadOne();
threadOne.start();
threadOne.interrupt();
}
执行结果:
总结:两个方法都是测试线程的中断状态,interrupted()方法会清除线程的中断状态;而isInterrupted()方法不会清除线程的中断状态
三. 不推荐使用的方法
1. stop() 方法
Jdk解释说明:Forces the thread to stop executing.
由于该方法是强制性停止线程执行,可能导致一些资源不能被正常回收。因此不推荐使用。
2. destroy()方法
Jdk解释说明:This method was originally designed to destroy this thread without
any cleanup
此方法最初旨在不进行任何清理的情况下破坏此线程,资源不能回收。
3. suspend()方法
Jdk解释说明:This method has been deprecated, as it is inherently deadlock-prone.
If the target thread holds a lock on the monitor protecting a critical system
resource when it is suspended, no thread can access this resource until the target
thread is resumed
此方法可能导致锁无法被释放,从而导致死锁。
4. resume()方法
Jdk解释说明:This method exists solely for use with {@link #suspend}, which has been
deprecated because it is deadlock-prone.
与suspend方法结合使用,由于suspend可能产生死锁问题,使得resume也被弃用
5. countStackFrames()方法
Jdk解释说明:Counts the number of stack frames in this thread. The thread must
be suspended.
很危险的一个方法,计算此线程中的堆栈帧数,当前线程必须被挂起。
总之这些被弃用的方法,总有致命的缺点,所以我们还是听从Jdk官方的建议,尽量不使用这些方法!