目录
1. 饥饿
饥饿是指一个可运行的进程尽管能继续执行,但被调度器无限期地忽视,而不能被调度执行的情况。
比如当前线程处于一个低优先级的情况下,操作系统每次都调用高优先级的线程运行,就会导致当前线程虽然可以运行,但是一直不能被运行的情况。
2. 线程的生命周期
线程的生命周期共有 6 种状态,分别是:新建 New
、运行(可运行)Runnable
、阻塞Blocked
、计时等待Timed Waiting
、等待Waiting
和终止Terminate
。
(1)当你声明一个线程对象时,线程处于新建状态,系统不会为它分配资源,它只是一个空的线程对象。
(2)调用 start()
方法时,线程就成为了可运行状态,至于是否是运行状态,则要看系统的调度了。
(3)调用了 sleep()
方法、调用 wait()
方法和 IO 阻塞时,线程处于等待、计时等待或阻塞状态。
(4)当 run()
方法执行结束后,线程也就终止了。
package com.company;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadState state = new ThreadState();
//声明并实例化一个ThreadState对象
Thread thread = new Thread(state);
//利用这个名为state的ThreadState对象来创建Thread对象
System.out.println("Create new thread: " + thread.getState());
//使用getState()方法来获得线程的状态,并进行输出
thread.start();
//使用thread对象的start()方法来启动新的线程
System.out.println("Start the thread: " + thread.getState());
//输出线程的状态
Thread.sleep(100);
//通过调用sleep()方法使当前这个线程休眠100毫秒,从而使新的线程运行waitForAMoment()方法
System.out.println("Waiting for a moment (time): " + thread.getState());
//输出线程的状态
Thread.sleep(1000);
//使当前这个线程休眠1000毫秒,从而使新的线程运行waitForever()方法
System.out.println("Waiting for a moment: " + thread.getState());
//输出线程的状态
state.notifyNow();
// 调用state的notifyNow()方法
System.out.println("Wake up the thread: " + thread.getState());
//输出线程的状态
Thread.sleep(1000);
//使当前线程休眠1000毫秒,使新线程结束
System.out.println("Terminate the thread: " + thread.getState());
//输出线程的状态
}
}
class ThreadState implements Runnable {
public synchronized void waitForAMoment() throws InterruptedException {
wait(500);
//使用wait()方法使当前线程等待500毫秒
//或者等待其他线程调用notify()或notifyAll()方法来唤醒
}
public synchronized void waitForever() throws InterruptedException {
wait();
//不填入时间就意味着使当前线程永久等待,
//只能等到其他线程调用notify()或notifyAll()方法才能唤醒
}
public synchronized void notifyNow() throws InterruptedException {
notify();
//使用notify()方法来唤醒那些因为调用了wait()方法而进入等待状态的线程
}
@Override
public void run() {
//这里用异常处理是为了防止可能的中断异常
//如果任何线程中断了当前线程,则抛出该异常
try {
waitForAMoment();
// 在新线程中运行waitMoment()方法
waitForever();
// 在新线程中运行waitForever()方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. 线程demo
package com.company;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
private static ReentrantLock lock = new ReentrantLock();
private static int count = 0;
private static Condition condition = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(() -> {
// 加锁
lock.lock();
try {
while (true) {
if (count == 9) {
break;
}
if (count % 3 == 0) {
count++;
System.out.println("A");
// 唤醒其他等待线程
condition.signalAll();
}
else {
try {
condition.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
finally {
lock.unlock();
}
});
Thread threadB = new Thread(() -> {
// 加锁
lock.lock();
try {
while (true) {
if (count == 9) {
break;
}
if (count % 3 == 1) {
count++;
System.out.println("B");
// 唤醒其他等待线程
condition.signalAll();
}
else {
try {
condition.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
finally {
lock.unlock();
}
});
Thread threadC = new Thread(() -> {
// 加锁
lock.lock();
try {
while (true) {
if (count == 9) {
break;
}
if (count % 3 == 2) {
count++;
System.out.println("C");
// 唤醒其他等待线程
condition.signalAll();
}
else {
try {
condition.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
finally {
lock.unlock();
}
});
threadA.start();
threadB.start();
threadC.start();
}
}