java线程状态:
很好奇等待,阻塞有什么区别,我在Ubnutu 16.04中在创建了几个java线程,来查看java线程的等待,阻塞状态分别对应Ubuntu中线程(轻量级进程)的什么状态
代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.locks.ReentrantLock;
import chapter04.SleepUtils;
public class ThreadTest {
/**
* 等待
*/
public static void createWaitThread(String threadName,final Object lock) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, threadName);
thread.start();
}
/**
*
* @param lock
*/
public static void createSynLockedThread(String threadName,final Object lock) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
while(true);
}
}
}, threadName);
thread.start();
}
public static void createReenLockedThread(String threadName,final ReentrantLock reentrantLock) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
reentrantLock.lock();
while(true);
}
}, threadName);
thread.start();
}
public static void createSleepThread(String threadName) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
SleepUtils.second(1000);
}
}, threadName);
thread.start();
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
Object obj = new Object();
Object obj2 = new Object();
ReentrantLock reentrantLock = new ReentrantLock();
createWaitThread("WaitThread",obj);
createSynLockedThread("SynLockedThread1", obj2);
createSynLockedThread("SynLockedThread2", obj2);
createReenLockedThread("ReenLockedThread1",reentrantLock);
createReenLockedThread("ReenLockedThread2",reentrantLock);
createSleepThread("SleepThread");
}
}
import java.util.concurrent.TimeUnit;
public class SleepUtils {
public static final void second(long seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
}
}
}
先看一下linux有几种线程状态:
运行到br.readLine()时候的截图:
JConsole截图:
htop截图:
可以看到main线程处于RUNNABLE状态,对应的linux线程处于SLEEPING状态(注意:这里第一个并不是main线程,main可能是第二个,不过不管是哪个都是SLEEPING),可以推测JVM中线程跟Linux线程并不是一一对应,而是相对独立,因为“正常情况下”java RUNNABLE状态的线程对应Linux中RUNNING线程
但是又看到深入理解JVM中有一段话:
有点疑惑,因为可以从图中看到不只是main线程对应的java线程是SLEEPING而是所有java线程都SLEEPING,就算jvm通过其他线程唤醒main对应的linux线程也做不到了啊??
接下来输入字符并回车创建线程,然后有以下状态:
可以发现跟文章开头的java线程状态变迁图描述的一致(ReentrantLock使用了LockSupport)
再来看linux线程:
发现只有两个是R其他都是S,这里虽然没有写出线程的名字,但很明显那两个R肯定是SynLockedThread1/2和ReenLockedThread1/2中获得锁的那两个线程,也就是说其实java中的WAITEING,TIMED_WAITEING和BLOCKED在Linux上都是SLEEPING具体的差别可能是在JVM中有差别对待把,百度上搜了下资料也没发现答案。