【java基础】线程的状态与使用

306 阅读2分钟

我是 啤酒就辣条,一个Java。
学而时习之,不亦说乎?希望通过博客的形式,总结、分享,梳理自己、帮助他人。
另外,啤酒就辣条,味道不错哦~

线程的状态与转换

线程的六种状态

线程转换

  1. 开始:从New -> RUNNABLE。从线程诞生到运行状态,一般使用方法Thread.start()
  2. 内部运行:RUNNABLE状态包含RUNNING(运行中)和READY(就绪),从RUNNING->READY,用到方法yield(),使用yield()方法的线程会让出执行权
public class MyThread extends Thread {
    MyThread(String name){
        super(name);
    }
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println(getName()+":"+i);
            yield();
        }
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread("线程1");
        MyThread myThread2 = new MyThread("线程2");
        myThread1.start();
        myThread2.start();
    }
}
// 输出结果,两个线程交替打印
  1. 完美的结束:线程正常结束,从RUNNABLE -> TERMINATED
  2. 无奈的等待:由于其他线程持有锁,当前线程呈BLOCKED。知道锁被释放,并且挣得锁时进入RUNNABLE。尝试用synchronized关键字,此时获取执行权,当前线程时被动的
  3. 自愿的选择:除了被动的无奈,当前线程还可以主动地释放锁进入 WAITING或者TIMED_WAITING。可以使用wait()join()等方法。线程可以设置超时时间进入TIMED_WAITING。经典应用场景是生产者消费者模型。

PS:此处只是简单介绍几种线程状态的转化,更多关于并发的介绍将总结于并发模块。

线程的使用

最简单的方式有两种,继承Thread和实现Runnable

继承Thread

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i=0;i<10;i++){
            System.out.println(getName()+":"+i);
        }
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        myThread1.start();
    }
}

实现Runnable

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("子线程");
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
}

//***********当然上面可简化为
public class ThreadTest {
    public static void main(String[] args) {
        new Thread(()->{
            System.out.println("子线程");
        }).start();
    }
}

更加方便的线程池

还有类似于FutureCompletableFuture等强大的工具将总结于并发模块。

除了手动维护Thread,我们还可以利用线程池,这里有一份SpringBoot使用线程池的推荐代码。