线程的生命周期
当线程被创建并且启动后,它经历了五种状态,新建,就绪,运行,阻塞,死亡,当线程在运行的时候不能一直占有CPU的执行权,CPU会在每个线程之间进行调度,线程也会多次进行阻塞和运行状态的切换。
1.当线程对象被创建出来就进入到了新建状态,和其他的Java对象一样,仅仅是由Java虚拟机为其分配内存。
2.调用start方法后,线程进入到就绪状态,其实内部还是依赖jvm的调度,当jvm执行这个线程才进入到运行状态,否则就是就绪状态。
3.如果线程就绪状态获得了CPU的执行权,那么线程就会进入到运行状态,这个线程不会一直霸占CPU的执行权,在执行的过程中会被JVM从CPU上调度下来就进入到阻塞状态。
**线程进入到阻塞状态的情况:**
1.线程调用一个阻塞的方法,该方法返回之前线程一直阻塞。
2.线程调用sleep方法。
3.线程尝试获取同步监视器(锁),但是该同步监视器被其他线程所持有。
4.线程调用了suspend方法挂起线程。
**线程从阻塞情况进入到运行状态的情况:**
1.调用的阻塞方法返回。
2.调用的sleep方法到期。
3.线程成功获取同步监视器。
4.调用suspend方法挂起的线程,调用resume方法恢复。
4.在以下三种方式,线程就会进入到死亡状态:
1.run方法执行完毕,线程正常结束。
2.线程抛出异常。
3.直接调用一个stop方法结束线程。
线程的控制
**join线程:**让另外一个正在运行的线程等待当前线程完成
public class JoinTest {
public static void main(String[] args) {
new JoinTest().init();
}
public void init() {
MainThread mt = new MainThread();
mt.setName("主线程");
mt.start();
}
public class MainThread extends Thread{
@Override
public void run() {
for(int i=0;i<30;i++) {
if(i==10) {
JoinThread jt = new JoinThread();
jt.setName("加塞线程");
jt.start();
try {
jt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(this.getName()+","+i);
}
}
}
public class JoinThread extends Thread{
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println(this.getName()+","+i);
}
}
}
}
线程的睡眠
可以使用Thread类的sleep方法,可以让线程休眠一下。
public class JavaSleep {
public static void main(String[] args) {
for(int i=0;i<50;i++) {
System.out.println(i);
try {
//程序每隔一秒执行一次
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程让步
线程的让步:当前线程从CPU上调度下来,多个线程再次共同争抢CPU的执行权
public class ThreadYield extends Thread{
public ThreadYield() {
}
public ThreadYield(String msg) {
super(msg);
}
@Override
public void run() {
for(int i=0;i<50;i++) {
if(i==20) {
//线程的让步,线程从CPU上调度下来,两者再次共同争抢CPU的执行权
Thread.yield();
}
System.out.println(this.getName()+","+i);
}
}
public static void main(String[] args) {
ThreadYield ty1 = new ThreadYield("高级线程");
//可以设置线程优先级,有时候在windows下不起作用
ty1.setPriority(MAX_PRIORITY);
ThreadYield ty2 = new ThreadYield("低级线程");
ty2.setPriority(MIN_PRIORITY);
ty1.start();
ty2.start();
}
}