一 . 在java中有以下三种方法可以停止正在运行的线程:
1 . 使用退出标志使线程正常退出,也就是当run方法完成后线程终止
2 . 使用stop() 方法强行终止线程,但是不推荐这么做,因为stop()方法和suspend()及resume()方法一样是不安全的,使用它们可能产生不可预料的结果
3 . 使用interrupt()方法终止线程(注意:interrupt方法并不会马上停止当前线程,它仅仅是在当前线程中打了一个停止的标记)
二 . 关于interrupt(),isInterrupted(),interrupted()方法
1 . interrupt()方法:
// Interrupts this thread
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
2 . isInterrupted()方法:
/**
* Tests whether the current thread has been interrupted.
* The interrupted status of the thread is unaffected by this method.
* 测试当前线程是否已经被标记为中断状态,此方法不会改变当前线程的状态
*/
public boolean isInterrupted() {
return isInterrupted(false);//调用本地方法isInterrupted(boolean ClearInterrupted)
}
private native boolean isInterrupted(boolean ClearInterrupted);
3 . interrupted()方法:
/**
* Tests whether the current thread has been interrupted.
* The interrupted status of the thread is is cleared by this method。In
* other words, if this method were to be called twice in succession, the
* second call would return false
* 测试当前线程是否已经被标记为中断状态,此方法会清除当前线程的
* 中断状态,换句话说,如果这个方法被调用两次,第二次调用将会返回false
*/
public static boolean interrupted() {
return currentThread().isInterrupted(true);// 调用本地方法isInterrupted(boolean ClearInterrupted)
}
private native boolean isInterrupted(boolean ClearInterrupted);
下面的示例代码为中断主线程
public class MyThread extends Thread {
public MyThread(String threadName) {
super(threadName);
}
/**
* 主线程
* @Description
* @author niepei
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
MyThread thread = new MyThread("test");
thread.start();
Thread.sleep(1000);
Thread.currentThread().interrupt(); // 将主线程标记为中断
System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.currentThread().isInterrupted());//true
System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.currentThread().isInterrupted());//true
System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.interrupted());//true
System.out.println(Thread.currentThread().getName()+" interrupted : " + Thread.interrupted());//false
System.out.println("【 " + Thread.currentThread().getName() + "】 has end");
}
/**
* 重写run方法
* @see java.lang.Thread#run()
*/
@Override
public void run() {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
for(int i=1;i<=10000;i++){
System.out.println("i = " + i);
}
System.out.println("==============> " + Thread.currentThread().getName() + " has end ");
}
}
下面的示例代码为在主线程中中断其他线程:
public class MyThread extends Thread {
public MyThread(String threadName) {
super(threadName);
}
/**
* 主线程
* @Description
* @author niepei
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("--------------> " + Thread.currentThread().getName() + " has begin ");
MyThread thread = new MyThread("test");
thread.start();
Thread.sleep(1000);
thread.interrupt();
System.out.println(thread.getName()+" interrupted : " + thread.isInterrupted());//true
System.out.println("--------------> " + Thread.currentThread().getName() + " has end ");
}
/**
* 重写run方法
* @see java.lang.Thread#run()
*/
@Override
public void run() {
System.out.println("==============> " + Thread.currentThread().getName() + " has begin ");
for(int i=1;i<=500000;i++){
System.out.println("i = " + i);
}
System.out.println("==============> " + Thread.currentThread().getName() + " has end ");
}
}
三 . interrupt()方法 和 sleep()方法
当线程休眠时被中断:在sleep状态下中断某一线程,会进入随后的catch语句并 清除状态值 ,使之变成false
public class MyThread extends Thread {
public MyThread(String threadName) {
super(threadName);
}
/**
* 主线程
* @Description
* @author niepei
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
MyThread thread = new MyThread("test");
thread.start();
thread.interrupt();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【 " + Thread.currentThread().getName() + "】 has end ");
}
/**
* 重写run方法
* @see java.lang.Thread#run()
*/
@Override
public void run() {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
try {
System.out.println("--> run has begin");
Thread.sleep(200000);
System.out.println("--> run has end");
} catch (InterruptedException e) {
System.out.println("--> interrupt in sleep , interrupted : " + this.isInterrupted());
}
System.out.println("【 " + Thread.currentThread().getName() + "】 has end ");
}
}
运行结果如下:
【 main】 has begin
【 test】 has begin
--> run has begin
--> interrupt in sleep , interrupted : false
【 test】 has end
【 main】 has end
四 . suspend() 方法和 resume()方法
suspend()方法用于暂停当前线程,而resume()方法用于恢复线程的执行,但是这两个方法如果使用不当很容易造成公共同步对象的独占,使其他线程无法访问公共同步对象。
public class Test {
public synchronized void printString() {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
if (Thread.currentThread().getName().equals("A")) {
System.out.println("【 " + Thread.currentThread().getName() + "】 has been suspend");
Thread.currentThread().suspend();
}
System.out.println("【 " + Thread.currentThread().getName() + "】 has end ");
}
public static void main(String[] args) throws InterruptedException {
System.out.println("【 " + Thread.currentThread().getName() + "】 has begin ");
final Test test = new Test();
Thread thread1 = new Thread() {
@Override
public void run() {
test.printString();
}
};
thread1.setName("A");
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread() {
@Override
public void run() {
System.out.println("【 " + Thread.currentThread().getName() + "】 can't start,because printString() is locked by Thread 【A】 and suspend forever ");
test.printString();
}
};
thread2.setName("B");
thread2.start();
System.out.println("【 " + Thread.currentThread().getName() + "】 has end ");
}
}
运行结果如下:
【 main 】 has begin
【 A 】 has begin
【 A 】 has been suspend
【 main 】 has end
【 B 】 can't start,because printString() is locked by Thread 【A】 and suspend forever
五 . yield方法:yield()用于放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定有可能刚刚放弃又重新获取CPU时间片
六.线程的优先级:可以调用setPriority()方法设置线程的优先级,最高10,最低1,线程的优先级具有继承性,假设A线程启动了B线程,则B线程具有与A一样的优先级,高优先级的线程总是大部分先执行完,但不代表高优先级的线程总是全部先执行完
七.守护线程:java中有两种线程,一种用户线程一种守护线程,守护线程是一种特殊的线程,当进程中不存在非守护线程了则守护线程会自动销毁,典型的守护线程就是GC线程,当JVM实例中最后一个非守护线程执行结束之后,它才会和JVM一起结束工作。可以调用setDaemon(true)将当前线程设置为守护线程。