线程阻塞经常在Java面试被问到,比如:什么是线程阻塞?线程阻塞方法等问题,下面我就来详解线程阻塞@mikechen
什么是线程阻塞?
线程阻塞是指一个线程被挂起,暂时停止执行,直到某个条件满足或等待的时间到达后才会继续执行。
为什么会出现线程阻塞?
线程阻塞通常是因为某种等待条件没有得到满足,比如等待 I/O 操作完成、等待其他线程释放锁或信号量、等待某个事件的发生等。
线程阻塞通常是由于以下原因引起:
1.等待 I/O 操作
当线程需要进行 I/O 操作(如读写磁盘或网络通信)时,线程会被阻塞,直到 I/O 操作完成或者出现错误。
2.同步等待
当线程需要等待其他线程释放某个共享资源(如锁或信号量)时,线程会被阻塞,直到获取该资源并完成操作。
3.睡眠等待
当线程需要等待一段时间后再执行某个操作时,可以使用睡眠等待的方式,这时线程会被阻塞,直到等待时间结束。
4.等待信号
线程有时需要等待某个信号的到来,如 Unix 系统的信号机制,这时线程会被阻塞,直到信号到达并被处理。
线程阻塞的方法
Java 中常见的线程阻塞方法有以下几种:
1.sleep()方法
该方法会让线程睡眠一段时间,可以指定毫秒或纳秒的时间,使得线程暂停执行,等待指定时间后再被唤醒。
public class SleepDemo { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("Thread started."); try { Thread.sleep(5000); // 线程睡眠 5 秒钟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread finished."); }); thread.start(); try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }
2.join()方法
该方法会使调用线程等待目标线程执行完毕,直到目标线程终止才会返回。
public class JoinDemo { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("Thread started."); try { Thread.sleep(5000); // 线程睡眠 5 秒钟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread finished."); }); thread.start(); try { thread.join(); // 等待线程执行完毕 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Main thread finished."); } }
3.wait() 和 notify()
这是 Java 中线程间同步的两个基本方法,使用 wait() 方法可以使当前线程进入等待状态,直到其他线程调用 notify() 或 notifyAll() 方法将其唤醒。
public class WaitNotifyDemo { public static void main(String[] args) { Object lock = new Object(); Thread thread1 = new Thread(() -> { synchronized (lock) { System.out.println("Thread 1 started."); try { lock.wait(); // 线程 1 进入等待状态 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 1 finished."); } }); Thread thread2 = new Thread(() -> { synchronized (lock) { System.out.println("Thread 2 started."); lock.notify(); // 唤醒线程 1 System.out.println("Thread 2 finished."); } }); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }
4.I/O 阻塞方法
Java 中的 I/O 操作是阻塞式的,当输入或输出操作无法立即完成时,线程会被阻塞,直到 I/O 操作完成。
5.Lock 和 Condition方法
Java 中的 Lock 和 Condition 接口提供了更灵活的线程同步方式,可以使用 lock() 和 unlock() 方法控制线程的互斥访问,使用 Condition 接口的 await() 和 signal() 方法实现线程间协作。
以上就是线程阻塞的详解,更多多线程内容,请查看:Java多线程编程详解(看这篇就足够了)
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》