我是 啤酒就辣条,一个Java。
学而时习之,不亦说乎?希望通过博客的形式,总结、分享,梳理自己、帮助他人。
另外,啤酒就辣条,味道不错哦~
线程的状态与转换
线程的六种状态
线程转换
- 开始:从
New
->RUNNABLE
。从线程诞生到运行状态,一般使用方法Thread.start()
。 - 内部运行:
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();
}
}
// 输出结果,两个线程交替打印
- 完美的结束:线程正常结束,从
RUNNABLE
->TERMINATED
。 - 无奈的等待:由于其他线程持有锁,当前线程呈
BLOCKED
。知道锁被释放,并且挣得锁时进入RUNNABLE
。尝试用synchronized关键字,此时获取执行权,当前线程时被动的。 - 自愿的选择:除了被动的无奈,当前线程还可以主动地释放锁进入
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();
}
}
更加方便的线程池
还有类似于Future
和CompletableFuture
等强大的工具将总结于并发模块。
除了手动维护Thread,我们还可以利用线程池,这里有一份SpringBoot使用线程池的推荐代码。