线程中的核心操作
- 1:start()
- 2:中断(终止)一个线程
- 2.1:自己定义线程结束的代码
- 2.1.1 存在的问题
- 2.2:使用Thread提供的interrupt()方法和isInterrupted()
- 2.2.1 继续执行
- 2.2.2 立即结束
- 2.2.3 打印异常信息,再立即结束
- 2.2.1 继续执行
- 2
- 2
- 三级目录
1:start()
start() 真正的创建线程,(在内核中创建PCB,然后添加到链表中).
一个线程需要先通过run/lambda表达式,把先要完成的任务定义出来,start()才是真正创建线程,并开始执行.
核心:是否真的创建线程出俩,每个线程都是独立调度执行的,(相当于整个程序中多了一个执行流)
一个Thread对象,也是只能start()一次的,如果想要再创建一个线程,需要再创建另一个Thread对象.
public class Test4 {
public static void main(String[] args) {
Thread thread=new Thread(()->{
System.out.println("hello thread");
});
thread.start();
thread.start();
}
}
上述代码会抛异常.
正确写法应该是创建两个Thread对象,然后再分别start();
public class Test4 {
public static void main(String[] args) {
Thread thread=new Thread(()->{
System.out.println("hello thread");
});
Thread thread2=new Thread(()->{
System.out.println("hello thread2");
});
thread.start();
thread2.start();
}
}
2:中断(终止)一个线程
终止一个线程,在Java中,都只是"提醒,建议",真正要不要终止,还是由线程本体来决定.
比如:t线程正在执行,其他线程,只是提醒一下t是不是要终止了,t收到这样的提醒后,也还是根据自己的代码觉得是否要终止.
2.1:自己定义线程结束的代码
核心思路:需要让终止的线程的入口的方法尽快执行结束,(跳出循环,尽快return 都可以).
public class Demo1 {
public static boolean flg=true;
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
while(flg){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
for (int i = 0; i < 3; i++) {
System.out.println("hello main");
Thread.sleep(1000);
}
flg=false;
Thread.sleep(1000);
System.out.println(thread.isAlive());
}
}
2.1.1 存在的问题
上面的代码,有一个很明显的缺陷,那就是当main线程中执行到flg=false的时候,如果thread线程刚好处于阻塞状态,那么只能阻塞状态结束, 才能终止线程.
如果sleep()的时间比较长,那么代码的效率就比较低了.
2.2:使用Thread提供的interrupt()方法和isInterrupted()
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
while(!Thread.currentThread().isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
for (int i = 0; i <3 ; i++) {
System.out.println("hello main");
Thread.sleep(1000);
}
thread.interrupt();
}
}
currentThread():这个方法能够获取到当前线程,也就是能够获取到thread 这个引用.
isInterrupted();是线程内置的标志位,true表示这个线程要终止了,false 表示这个线程要继续执行.
thread.interrupt();通过这个方法,就相当于将标志位设置为true,同时,还可以唤醒sleep()等阻塞的方法.
有sleep()的时候,当触发Interrupt的时候,线程正在sleep,sleep被唤醒的同时,就会清除掉刚才的标志位(又改为false).
之所以要改回去,就是把控制权,交给程序员自己,当前线程是否要继续执行?,还是要立即结束?还是要等结束?让程序员自己写代码来决定.
2.2.1 继续执行
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
while(!Thread.currentThread().isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
for (int i = 0; i <3 ; i++) {
System.out.println("hello main");
Thread.sleep(1000);
}
thread.interrupt();
}
}
2.2.2 立即结束
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
while(!Thread.currentThread().isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
thread.start();
for (int i = 0; i <3 ; i++) {
System.out.println("hello main");
Thread.sleep(1000);
}
thread.interrupt();
}
}
2.2.3 打印异常信息,再立即结束
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
Thread thread=new Thread(()->{
while(!Thread.currentThread().isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
});
thread.start();
for (int i = 0; i <3 ; i++) {
System.out.println("hello main");
Thread.sleep(1000);
}
thread.interrupt();
}
}