Java多线程并发问题:同步锁和死锁示例

原创 秒速五厘米 2024-09-22 08:45 188阅读 0赞

在Java编程中,多线程并发会遇到各种问题,包括同步锁、死锁等。下面通过实例来解释这两种情况。

  1. 同步锁
    当一个线程访问共享资源时,通常需要使用某种形式的锁(如synchronized关键字)来保护共享资源不被其他线程同时访问。

    示例代码:

    1. // 假设我们有一个共享对象count
    2. private int count = 0;
    3. public synchronized void increment() {
    4. count++;
    5. notifyAll(); // 线程等待唤醒后继续执行
    6. }
    7. public synchronized void decrement() {
    8. if (count > 0) {
    9. count--;
    10. notifyAll();
    11. }
    12. }
    13. public static void main(String[] args) {
    14. MyCounter counter = new MyCounter();
    15. // 创建两个线程并发操作counter
    16. Thread incrementThread = new Thread(() -> {
    17. while (!counter.increment()) { // 线程等待锁
    18. try {
    19. // 线程休眠一段时间以避免CPU浪费
    20. Thread.sleep(100);
    21. } catch (InterruptedException e) {
    22. e.printStackTrace();
    23. }
    24. }
    25. }));
    26. Thread decrementThread = new Thread(() -> {
    27. while (!counter.decrement())) { // 线程等待锁
    28. try {
    29. // 同理,线程休眠以避免CPU浪费
    30. Thread.sleep(100);
    31. } catch (InterruptedException e) {
    32. e.printStackTrace();
    33. }
    34. }
    35. }));
    36. incrementThread.start();
    37. decrementThread.start();
    38. // 等待两个线程执行完毕后打印结果
    39. try {
    40. incrementThread.join(); // 线程等待
    41. decrementThread.join();
    42. } catch (InterruptedException e) {
    43. e.printStackTrace();
    44. }
    45. System.out.println("最终计数: " + counter.getCount());
    46. }

在上述代码中,我们创建了一个共享的计数器count。两个线程分别执行incrementdecrement操作。通过使用synchronized关键字来确保线程安全。

  1. 死锁
    当两个或多个线程因争夺资源而造成的一种互相等待的现象时,就会发生死锁。

    示例代码(有死锁风险):

    1. // 假设我们有一个共享对象count
    2. private int count = 0;
    3. public synchronized void increment() {
    4. if (count < 10) { // 确保计数不会超过10,否则会出现死锁
    5. count++;
    6. notifyAll();
    7. } else {
    8. System.out.println("错误:尝试将计数器提升到10以上,但资源已耗尽。");
    9. }
    10. }
    11. public static void main(String[] args) {
    12. MyCounter counter = new MyCounter();
    13. // 创建两个线程并发操作counter
    14. Thread incrementThread = new Thread(() -> {
    15. while (!counter.increment())) { // 线程等待锁
    16. try {
    17. // 线程休眠一段时间以避免CPU浪费
    18. Thread.sleep(100);
    19. } catch (InterruptedException e) {
    20. e.printStackTrace();
    21. }
    22. }
    23. }));
    24. Thread decrementThread = new Thread(() -> {
    25. while (!counter.decrement())) { // 线程等待锁
    26. try {
    27. // 同理,线程休眠以避免CPU浪费
    28. Thread.sleep(100);
    29. } catch (InterruptedException e) {
    30. e.printStackTrace();
    31. }
    32. }
    33. }));
    34. incrementThread.start();
    35. decrementThread.start();
    36. // 等待两个线程执行完毕后打印结果
    37. try {
    38. incrementThread.join(); // 线程等待
    39. decrementThread.join();
    40. } catch (InterruptedException e) {
    41. e.printStackTrace();
    42. }
    43. System.out.println("最终计数: " + counter.getCount());
    44. }

在这个示例中,我们创建了两个线程分别执行incrementdecrement操作。但是,我们在increment方法中添加了一个条件判断:如果计数器值超过10,就会抛出一个错误并停止计数。这种情况下,线程会一直等待直到计数器被正确释放。

这就是死锁的一种情况,当资源分配不均衡且循环等待时,就可能导致死锁。

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

发表评论

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

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

相关阅读