Java中线程同步问题:锁、条件变量与问题实例

原创 待我称王封你为后i 2024-11-12 15:33 111阅读 0赞

在Java中,线程同步是一个重要的概念,它确保了多个线程在访问共享资源时的一致性和线程安全。以下是一些常见的线程同步机制和它们的基本用法:

1.锁(Locks)

Java提供了多种锁机制,其中最基本的是synchronized关键字和ReentrantLock类。

  • synchronized关键字:可以用来修饰方法或者代码块,确保同一时间只有一个线程可以执行该段代码。
    ```java public class Counter {
    private int count =0;

    public synchronized void increment() {
    count++;
    }

    public synchronized int getCount() {
    return count;
    }
    }
    - **ReentrantLock类**:是一个可重入的互斥锁,提供了与`synchronized`关键字类似的同步功能,但提供了更灵活的加锁和解锁操作。javaimport java.util.concurrent.locks.ReentrantLock;

    public class Counter {
    private final ReentrantLock lock = new ReentrantLock();
    private int count =0;

    public void increment() {
    lock.lock();
    try {
    count++;
    } finally {
    lock.unlock();
    }
    }

    public int getCount() {
    lock.lock();
    try {
    return count;
    } finally {
    lock.unlock();
    }
    }
    }
    ```###2.条件变量(Condition Variables)

条件变量允许一个线程在某个条件为真之前挂起,并在条件变为真时被唤醒。Condition接口和ReentrantLock类一起使用。

```javaimport java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedBuffer {
private final Object[] items;
private int putPtr, takePtr, count;
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();

public BoundedBuffer(int capacity) {
items = new Object[capacity];
}

public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await();
}
items[putPtr] = x;
if (++putPtr == items.length) putPtr =0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}

public Object take() throws InterruptedException {
lock.lock();
try {
while (count ==0) {
notEmpty.await();
}
Object x = items[takePtr];
if (++takePtr == items.length) takePtr =0;
—count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
```###问题实例一个常见的线程同步问题是死锁,当两个或多个线程在等待对方释放资源时发生。例如:

```javapublic class DeadlockExample {
private static final Object resource1 = new Object();
private static final Object resource2 = new Object();

public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println(“Thread1 acquired both resources”);
}
}
}).start();

new Thread(() -> {
synchronized (resource2) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println(“Thread2 acquired both resources”);
}
}
}).start();
}
}
```在这个例子中,两个线程分别尝试获取两个资源,但由于它们获取资源的顺序不同,导致死锁。

线程同步是并发编程中的一个重要话题,正确使用同步机制可以避免数据不一致和死锁等问题。

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

发表评论

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

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

相关阅读

    相关 Java中线同步问题实例分析

    在Java中,线程同步是一个非常重要的概念,它确保了多个线程在访问共享资源时的一致性和线程安全。以下是一些常见的线程同步问题实例分析: ###1.竞态条件(Race Cond