理解并避免Java多线程同步问题示例

原创 我会带着你远行 2024-11-15 21:45 134阅读 0赞

在Java多线程编程中,同步问题是非常常见的。以下是一些示例来帮助你理解和避免这些问题:

  1. 共享资源导致的竞态条件(Race Condition)
    ```java
    class Counter {
    int count = 0;

    synchronized void increment() {

    1. count++;

    }

    synchronized int decrement() {

    1. if (count > 0) {
    2. count--;
    3. }
    4. return count;

    }
    }

public class RaceConditionExample {
Counter counter = new Counter();

  1. // 竞态条件
  2. new Thread(() -> {
  3. for (int i = 0; i < 10000; i++) {
  4. counter.increment();
  5. }
  6. })).start();
  7. // 同步调用,避免竞态条件
  8. for (int i = 0; i < 10000; i++) {
  9. counter.decrement();
  10. try {
  11. Thread.sleep(1); // 线程睡眠
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. public static void main(String[] args) {
  17. RaceConditionExample example = new RaceConditionExample();
  18. example.run();
  19. }

}

  1. 在这个例子中,两个线程同时尝试增加计数器的值,导致了竞态条件。
  2. 2. **死锁(Deadlock)**:
  3. ```java
  4. class Resource {
  5. // 假设资源是互斥的
  6. boolean available = true;
  7. synchronized void acquire() {
  8. if (available) {
  9. available = false;
  10. return;
  11. }
  12. try {
  13. wait();
  14. } catch (InterruptedException e) {
  15. e.printStackTrace();
  16. Thread.currentThread().interrupt(); // 线程中断,避免死循环
  17. }
  18. }
  19. synchronized void release() {
  20. available = true;
  21. notifyAll(); // 唤醒等待的线程
  22. }
  23. }
  24. public class DeadlockExample {
  25. private Resource resource1 = new Resource();
  26. private Resource resource2 = new Resource();
  27. public void acquireResources() {
  28. resource1.acquire(); // 资源1获得锁
  29. resource2.acquire(); // 资源2获得锁
  30. }
  31. public void releaseResources() {
  32. resource1.release(); // 资源1释放锁
  33. resource2.release(); // 资源2释放锁
  34. }
  35. public static void main(String[] args) {
  36. DeadlockExample example = new DeadlockExample();
  37. example.acquireResources(); // 获取资源,形成死锁
  38. example.releaseResources(); // 无法释放资源,导致死锁
  39. }
  40. }

在这个例子中,两个线程分别获取了资源1和资源2的锁。当一个线程完成操作后试图释放锁,但因为另一个线程持有资源1或资源2的锁,所以无法解锁并释放资源。这就形成了死锁。

为了避免这些同步问题,你可以使用Java并发工具类(如java.util.concurrent.locks.LockReentrantLock等)来更精确地控制锁的获取和释放。

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

发表评论

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

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

相关阅读