java线程多线程状态线程状态
学过Java的人都知道,Java是少数的集中支持多线程的语言之一,大多数的语言智能运行单独的一个程序块,无法同时运行不同的多个程序块,Java的多线程机制弥补了这个缺憾,他可以让不同的程序块一起运行,这样可以让程序运行更加顺畅,同时也达到了多任务处理的目的:
一、线程和进程的概念
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
进程是程序的一个动态执行过程,是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。“同时”执行是人的感觉,在线程之间实际上轮换执行。
二、java中实现的方式
java中有两个实现多线程的方式,
- 可以实现implements Runnable 接口,好处灵活,还可以多实现,继承其他的基类。
- 可以继承Thread 基类,不可以再继承其他基类了,智能再实现其他的接口,相对不灵活。
具体的代码如下;
A> 实现Runnable 的方式
public class MyThreads implements Runnable{
@Override
public void run() {
String id = Thread.currentThread().getName();
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(id+" 得到的 "+i);
}
}
public static void main(String[] args) throws InterruptedException {
MyThreads mt = new MyThreads();
Thread t1 = new Thread(mt);
t1.setName("王老吉");
Thread t2 = new Thread(mt);
t2.setName("加多宝");
t1.start();t2.start();
t1.join();
t2.join();
}
B>继承 Thread的方式
public class MyRunnable extends Thread {
private volatile int sum = 30;
@Override
public void run() {
String id = Thread.currentThread().getName();
for (int i = sum; i > 0; i--) {
try {
Thread.sleep(50);
sum--;
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(id + "得到" + sum);
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable t1 = new MyRunnable();
t1.setName("王老吉");
MyRunnable t2 = new MyRunnable();
t2.setName("加多宝");
t1.start();
t2.start();
t1.join();
t2.join();
}
}
三、多线程的几种状态
新建(new)
新建一个线程的对象。
可运行(runable)
线程对象创建后,其他线程调用该线程的start方法。或者该线程位于可运行线程池中等待被线程调用,已获取cpu的使用权。
运行(running)
可运行的线程获取了cpu的使用权,执行程序代码/
阻塞(block)
由于某些原因该线程放弃了cpu的使用权。停止执行。除非线程进入可运行的状态,才会有机会获取cpu的使用权。
1. 等待阻塞:运行中的线程执行wait方法,这时候该线程会被放入等待队列。
2. 同步阻塞:运行中的线程获取同步锁,如果该同步锁被别的线程占用,这个线程会成被放入锁池,等待其他线程释放同步锁。
3. 其他阻塞:运行的线程执行sleep或者join方法这个线程会成为阻塞状态。当sleep超时,join等待线程终止,该线程会进入可运行状态。
死亡(dead)
线程run mian 执行完毕后,或者因为某些异常产生退出了 run 方法,该线程的生命周期结束。
状态的切换方法
各种状态一目了然,值得一提的是"blocked"这个状态:
线程在Running的过程中可能会遇到阻塞(Blocked)情况
调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。
此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。
参考:https://www.cnblogs.com/wxd0108/p/5479442.html
https://www.cnblogs.com/wumingcong/p/3205706.html