调用 start 方法,才真的在操作系统的底层创建出一个线程
run方法只是描述了线程要执行的任务,只是一个普通方法
run方法应该由start内部来调用的,多线程编程应该用start方法
在Thread中的子类中重写run方法,就会被start里面创建的新线程来执行
start内部调用操作系统提供的api,创建线程。
然后让线程执行run方法中的代码
让run方法执行完,线程就结束了
while (true) {//这种无限循环的情况,线程结束不了
System.out.println("dxc1");//当然强制终止线程,线程也没了,这是特殊手段
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
1)手动设置一个标志位,来作为循环的判定条件
while (!isQuit) {//通过自己设定的变量,来控制循环是否结束,从而影响到线程是否结束
System.out.println("dxc1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//这里的isQuit这个变量相当于在线程中读取。在main中修改
//当然如果这样来进行,其实也存在一定的缺陷
2)直接借助Thread实例中自己提供的一个标志位
我们虽然不能直接引用到这个标志位变量,咱们可以通过一些方法来操作标志位
Thread t = new Thread() {
@Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
// 做一些其他工作~~
break;
}
}
}
在t的线程代码中,存在两种情况
- 执行打印和while循环判定(线程处于就绪状态
- 进行sleep(线程处于阻塞/休眠状态
调用interrupt方法时
interrupt方法这个方法,说是中断线程,但是不是直接立即马上的杀死线程
具体线程怎么退出,这是线程代码自己说了算
join可以控制线程结束的先后顺序
join会进行等待,直到t线程执行完(t的run方法结束了
public class Demo12 {
public static void main(String[] args) {
Thread t = new Thread(() -> {//
for (int i = 0; i < 5; i++) {//打印5次hello thread
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
System.out.println("t 线程尚未结束. ");
// 主线程中, 可以使用 join 来进行等待.
try {
t.join();//当线程t在运行的时候,进行阻塞等待,一直到线程t的run方法执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t 线程已经结束. ");
}
}
拿到这个引用,才能做出一些后续操作,很多和线程相关的操作,都是依赖这样的引用
1)如果通过继承Thread来创建的线程。此时直接run方法中通过this,就能拿到这个线程的实例
Thread t = new Thread() {
@Override
public void run() {
while (!this.isInterrupted()) {
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//做一些其它工作
break;
}
}
}
};
t.start();
2)更常见的是使用Thread里面的一个静态方法,currentThread(),哪个线程调用这个静态方法,就能够返回哪个线程的Thread实例引用,这种获取方式,可以在任何代码中使用。
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (this.isInterrupted()) {
}
}
});
在这个代码中,通过Thread.isInterrupted方法是不能直接调用的。
仔细一看,当前run不是Thread的方法,而是Runnable的方法
因此,this也就是指向的是Runnable
当然没有Thread类的属性和方法
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
}
}
});
此时run虽然仍是Runnable的方法
但是是通过这个Thread的currentThread来获取到线程实例的
Thread.currentThread()这个方法是那个线程调用,就返回那个线程的实例
调用sleep的线程就会阻塞等待
取决于sleep中指定的时间