一、线程的让步
Thread.yield();//运行态–>就绪态
public class ThreadYield {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
while(Thread.activeCount()>1){//使用调试的方法运行
Thread.yield();
}
System.out.println(Thread.currentThread().getName());
}
}
二、线程的等待
(1)join
public static void main(String[] args) throws InterruptedException {
Thread t= new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
t.start();
//先将T线程执行完毕,再往下执行
t.join();
t.join(2000);
System.out.println(Thread.currentThread().getName());
}
(2)结合activeCount()+yield();使用
public class ThreadYield {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}).start();
while(Thread.activeCount()>1){
Thread.yield();
}
System.out.println(Thread.currentThread().getName());
}
}
三、线程中断
(1)isInterrupted()
I(2)nterrupted()
不是真实的直接中断,而是告诉某个线程需要中断,具体是否中断由该线程自己决定
(3)interrupt()
(4)过期方法stop();
注:1.线程启动以后:中断标志位=false
2.在线程运行态中,处理线程中断,需要自行通过判断中断标志位,来进行中断的处理逻辑。通过方法thread.isInterrupted()/Thread.interrupted()
3.线程因调用wait()/join()/sleep()处于阻塞状态时,将线程中断,会造成:
(1)在这三个阻塞方法所在的代码行,直接抛出InterruptedException异常
(2)抛出异常之后,重置线程的中断标志位(=true)
4.static void interrupted():返回中断标志位,并重置标志位
void isInterrupted():返回中断标志位
5.自定义的标志位满足不了线程处于阻塞状态时,中断操作
public class InterruptThread {
//中断一个线程,但是线程没有处理中断
public static void test1(){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
while (true){
}
}
});
t.start();
t.interrupt();
}
//
public static void test2() throws InterruptedException {
Thread t=new Thread(new Runnable() {
@Override
public void run() {//线程运行状态下处理中断标志
for(int i=0;i<50;i++){
System.out.println(i+""+Thread.currentThread().isInterrupted());
}
// while (!Thread.currentThread().isInterrupted()){
while (!Thread.interrupted()){
System.out.println(Thread.currentThread().getName());
}
}
});
t.start();//t线程中的中断标志位=false
t.interrupt();//t线程中的中断标志位=true
}
public static void test3() throws InterruptedException {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().isInterrupted());//true
//线程处于调用wait()/join()/sleep()阻塞的时候,如果把当前线程中断,会直接抛出一个异常
//阻塞状态时,通过捕获及处理异常,来处理线程的中断逻辑
//抛出异常以后线程的标志位被重置
Thread.sleep(9999999);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted());//false
}
}
});
t.start();//t线程中的中断标志位=false
t.interrupt();//t线程中的中断标志位=true
}
public static void test4() throws InterruptedException {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<10;i++){
System.out.println(Thread.currentThread().isInterrupted());
// System.out.println(Thread.interrupted());//返回中断标志位,并重置标志位
}
}
});
t.start();//t线程中的中断标志位=false
t.interrupt();//t线程中的中断标志位=true
}
private static volatile boolean IS_INTERRUPTDE;
//使用自定义的中断标志位
public static void test5(){
Thread t=new Thread(new Runnable() {
@Override
public void run() {
//自定义的标志位 能满足线程处于运行态的中断操作
// while (!IS_INTERRUPTDE){
// System.out.println(Thread.currentThread().getName());
// }
//自定义的标志位满足不了西安城处于阻塞状态时,中断操作
try {
Thread.sleep(99999);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
IS_INTERRUPTDE=true;
}
public static void main(String[] args) throws InterruptedException {
//test1();
//test2();
// test3();
// test4();
test5();
}
}
四、守护线程
至少有一个非守护线程没有被销毁,进程就不会退出
非守护线程一般可以称为工作线程,守护线程可以称为后台线程
public class DaemonThread {
public static void main(String[] args) {
Thread t=new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(99999999L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//设置线程为守护线程
t.setDaemon(true);
t.start();
}
}
五、线程的启动
run()和start()
MyThread myThread=new MyThread();
myThread.start();
//run 方法直接调用,不会启动现线程,只会在当前main线程中调用run方法
//myThread.run();