Java多线程同步:死锁、饥饿等问题示例

原创 深藏阁楼爱情的钟 2024-09-15 10:30 135阅读 0赞

在Java编程中,多线程的同步是非常关键的一部分。它可以帮助我们避免一些诸如死锁(Dead Lock)、饥饿(Starvation)等问题。

  1. 死锁:当两个或更多的线程因争夺资源而造成的一种互相等待的现象称为死锁。

示例代码:

  1. class DeadLockExample {
  2. Object lock1 = new Object();
  3. Object lock2 = new Object();
  4. void method1() {
  5. synchronized (lock1) {
  6. try {
  7. synchronized (lock2) {
  8. // 这里的操作会导致两个线程都等待对方释放锁
  9. }
  10. } finally {
  11. lock1.notifyAll(); // 通知所有等待锁1的线程
  12. }
  13. }
  14. }
  15. void method2() {
  16. synchronized (lock2) {
  17. try {
  18. synchronized (lock1) {
  19. // 这里的操作会导致两个线程都等待对方释放锁
  20. }
  21. } finally {
  22. lock2.notifyAll(); // 通知所有等待锁2的线程
  23. }
  24. }
  25. }
  26. public void startThreads() {
  27. new Thread(() -> method1()).start();
  28. new Thread(() -> method2()).start();
  29. }
  30. }

当线程method1进入同步块并获取到锁lock1后,它等待锁lock2释放。同样,线程method2在等待锁lock1释放的同时,也在等待锁lock2释放。

这样的设计会导致两个线程都处于等待状态,从而产生死锁。

  1. 饥饿(Starvation):当一个线程因为被剥夺执行机会而无法继续执行其任务时,就出现了饥饿现象。

示例代码:

  1. class StarvationExample {
  2. Object lock = new Object();
  3. void task() {
  4. synchronized (lock) {
  5. lock.notifyAll(); // 通知所有等待锁的线程
  6. try {
  7. // 模拟耗时操作
  8. Thread.sleep(5000);
  9. } catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. }
  13. }
  14. public void startTask() {
  15. new Thread(() -> task()).start();
  16. }
  17. }

在这个例子中,线程task执行一个耗时的操作后通知所有等待锁的线程。然而,如果线程task被其他更高优先级的任务抢占,它将无法完成通知和耗时操作。

这种情况下,线程task就会发生饥饿现象。

文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。

发表评论

表情:
评论列表 (有 0 条评论,135人围观)

还没有评论,来说两句吧...

相关阅读