Java中常用的同步器包括:
1.synchronized关键字
在Java中,使用synchronized关键字可以对代码块或方法进行同步,使得在同一时刻只有一个线程可以执行该代码块或方法。
下面是一个使用synchronized关键字同步的示例代码:
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
2.ReentrantLock类
ReentrantLock是一个可重入的互斥锁,它可以和synchronized关键字一样实现对临界区的同步。使用ReentrantLock时需要手动获取和释放锁。
下面是一个使用ReentrantLock同步的示例代码:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private int count = 0;
private ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
3.Semaphore类
Semaphore是一个信号量,它可以限制同时访问某一资源的线程数量。Semaphore可以用来实现生产者-消费者模型等。
下面是一个使用Semaphore实现生产者-消费者模型的示例代码:
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private final Semaphore producerSemaphore = new Semaphore(1);
private final Semaphore consumerSemaphore = new Semaphore(0);
private int data;
public void produce(int newData) throws InterruptedException {
producerSemaphore.acquire();
data = newData;
consumerSemaphore.release();
}
public int consume() throws InterruptedException {
consumerSemaphore.acquire();
int consumedData = data;
producerSemaphore.release();
return consumedData;
}
}
4.Condition接口
Condition是一个条件变量,它可以和Lock一起使用,可以实现更加灵活的线程同步。
下面是一个使用Condition实现等待-通知模型的示例代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
private int data;
private Lock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();
private boolean full = false;
public void put(int newData) throws InterruptedException {
lock.lock();
try {
while (full) {
notFull.await();
}
data = newData;
full = true;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public int take() throws InterruptedException {
lock.lock();
try {
while (!full) {
notEmpty.await();
}
int takenData = data;
full = false;
notFull.signal();
return takenData;
} finally {
lock.unlock();
}
}
}
5.CountDownLatch类
CountDownLatch是一个同步工具类,它可以使一个或多个线程等待其他线程完成操作后再执行。CountDownLatch的使用需要指定计数器的初始值,并通过await()方法等待计数器归零,同时通过countDown()方法将计数器减一。
下面是一个使用CountDownLatch实现等待其他线程完成操作的示例代码:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int count = 5;
CountDownLatch latch = new CountDownLatch(count);
for (int i = 0; i < count; i++) {
Thread thread = new Thread(() -> {
// 模拟线程操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "执行完成");
// 计数器减一
latch.countDown();
});
thread.start();
}
// 等待计数器归零
latch.await();
System.out.println("所有线程执行完成");
}
}
6.CyclicBarrier类
CyclicBarrier也是一个同步工具类,它可以使一组线程相互等待,直到所有线程都到达某个屏障点后再同时执行。CyclicBarrier的使用需要指定参与线程的数量,并通过await()方法等待所有线程到达屏障点,同时通过reset()方法将屏障重置,可以用于多次使用。
下面是一个使用CyclicBarrier实现线程同步的示例代码:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int count = 3;
CyclicBarrier barrier = new CyclicBarrier(count, () -> {
System.out.println("所有线程执行完成");
});
for (int i = 0; i < count; i++) {
Thread thread = new Thread(() -> {
// 模拟线程操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程" + Thread.currentThread().getName() + "执行完成");
try {
// 等待其他线程
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
});
thread.start();
}
}
}
以上是Java中常用的同步器,不同的同步器有着不同的适用场景和使用方式,需要根据实际情况选择合适的同步器进行使用。