本文仅记笔者学习之时紧要之处,疏漏难免,详参https://blog.csdn.net/xuxurui007/article/details/7685076
一、线程五种状态
在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡。
第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep(睡眠),suspend(挂起),wait(等待)等方法都可以导致线程阻塞。
第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。
二、线程启动
线程的启动并不是简单的调用了run方法,而是由一个线程调度器来分别调用所有线程的run方法
普通的run方法如果没有执行完是不会返回的,也就是会一直执行下去,这样run方法下面的方法就不可能会执行了
线程里的run方法不同,它只有一定的CPU时间,执行过后就给别的线程了,这样反复的把CPU的时间切来切去,因为切换的速度很快,所以我们就感觉是很多线程在同时运行一样
两种方法:
a.继承Thread类,重写里面的run方法,用start方法启动线程
public class Treadtest {
public static void main(String[] args) throws InterruptedException {
Thread process = new processTread();
process.start(); //启动线程
}
}
// 继承Thread类并重写run方法
class processTread extends Thread{
public void run() {
Thread.currentThread().setName("子线程1");
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() +"--->" + i);
}
}
}
b.实现Runnable接口,实现里面的run方法,用new Thread(Runnable target).start()方法来启动
public class RunableTest {
public static void main(String[] args) {
DemoTest ra = new DemoTest();
Thread t = new Thread(ra);
t.start();
}
}
class DemoTest implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("Runable 实现");
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "-->" + i);
}
}
}
start()和run()区别:
start()用来启动一个线程,run()用来开始执行该线程
1. mythread.start()会启动“线程mythread”,这时此线程是处于就绪状态, 并没有运行。这时无需等待mythread.run方法体代码执行完毕,可以直接继续执行下面的代码;
2. 调用mythread线程的run()方法会运行在“线程mythread”上,这里方法run()称为线程体,它包含了要执行的这个线程的内容, Run方法运行结束, 此线程终止。然后CPU再调度其它线程。