提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
多线程的基础问题
给线程起名字(方便调试)
Thread t=new Thread(“这是俺的线程”)
Thread t = new Thread(() -> {
while (true) {
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "这是俺的线程");
前台线程和后台线程:
咱们默认创建的线程是“前台线程,前台线程会阻止程序的退出,如果main运行完了,前台线程还没完,进程不会退出”
如果是后台线程,不会阻止进程退出,如果main等其他的前台线程执行完了,这个时候,及时后台线程没执行玩,进程也会退出
代码演示:
package Threading;
public class demo7 {
public static void main(String[] args) {
Thread t = new Thread(() -> {
while (true) {
System.out.println("hello");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "这是俺的线程");
t.setDaemon(true);
//使用setDaemon设置成后台线程
//设置操作得在start之前,如果线程启动了,就改动不了了
t.start();
System.out.println("main线程执行结束. ");
}
}
执行效果:
核心代码:
t.setDaemon(true)设置为后台线程
start和run区别
1.调用start才会创建线程,不调用start没有创建线程(在内核里面创建pcb)
直接调用run并没有创建线程,知识在原来的线程中运行代码
调用start,则是创建了线程,在新县城中执行代码(和原先的线程是并发的)
package Threading;
//演示run,和start区别
class MyThread2 extends Thread{
@Override
public void run(){
while(true){
System.out.println("hello thread");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public class demo9 {
public static void main(String[] args) {
MyThread2 t=new MyThread2();
t.start();
// t.run();
while(true){
System.out.println("hello main");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
start并发,创建了一个新县城t
run只执行了main线程中的代码
**
线程怎么中断:
**
方式1:1.自己设置一个标志位:作为线程是否结束的标记
package Threading;
//线程中断的方式1:设置标志位自动线程终端
public class demo10 {
private static boolean isQuit=false;
public static void main(String[] args) {
Thread t=new Thread(()->{
while(!isQuit){
System.out.println("hello thread");
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
t.start();
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
isQuit=true;
System.out.println("设置让t线程结束");
}
}
2.通过标准库里面自带一个标志位:
package Threading;
//使用thread提供的方法来终端线程
public class demo11 {
public static void main(String[] args) {
Thread t=new Thread(()->{
while(Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// e.printStackTrace();
// 方式1:立即结束线程
break;
// 方式2:啥都不做,不做理会,线程继续执行
//方式3:线程稍后处理
//Thread.sleep(1000);
//break;
}
}
System.out.println("t 线程执行完了");
});
t.start();
try{
Thread.sleep(S1000);
}catch (InterruptedException e){
e.printStackTrace();
}
t.isInterrupted();
System.out.println("设置让t线程结束");
}
}
核心代码:
Thread.currentThread().isInterrupted())
调用thread类的静态方法,通过这个方法可以拿到当前线程的实例(拿到当前线程对应的thread对象)
.isInterrupted()是在判定标志位
线程等待join
在main函数中调用t.join就是让mian线程阻塞等待,等到t执行完了,main才继续执行
package Threading;
//演示阻塞等待join
public class demo12 {
public static void main(String[] args) {
Thread t=new Thread(()->{
for (int i = 0; i <5 ; i++) {
System.out.println("hello thread!");
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
});
t.start();
System.out.println("main线程join 之前");
try{
t.join();
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("main 线程 join 之后");
}
}
阻塞线程sleep:
指定休眠的时间让线程休息一会,调用sleep这个pcb就会被移动到另外的阻塞队列中