Java实现多线程同步五种方法详解
什么是多线程同步
在多线程编程中,多个线程访问相同的共享数据时,可能会导致数据异常,因此需要实现多线程同步,以保证数据的正确性。多线程同步的基本思路是,在一个线程访问共享数据时,其他线程不能访问该数据,待该线程访问完毕后,其他线程才能访问该数据。
实现多线程同步的五种方法
Java实现多线程同步的方法较多,下面列举了常用的五种方法。
1. synchronized关键字
synchronized关键字用于修饰方法或代码块,用来实现线程的同步。对于修饰方法的情况,synchronized会锁住整个方法,即一个线程访问该方法时,其他线程必须等待该线程访问完毕才能访问该方法;对于修饰代码块的情况,synchronized会锁住代码块,即一个线程进入代码块后,其他线程必须等待该线程退出代码块才能进入代码块。
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
}
2. ReentrantLock类
ReentrantLock是JDK提供的一个Lock接口的实现类,它可以实现更加灵活的线程同步。与synchronized相比,ReentrantLock提供了可中断(可以被其他线程打断)的锁获取、公平锁、多个条件变量等功能。
public class ReentrantLockExample {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
3. AtomicInteger类
AtomicInteger是JDK提供的一个原子类,可以保证对该类的操作都是原子性的。通过使用AtomicInteger类,可以避免使用synchronized或ReentrantLock进行线程同步。
public class AtomicIntegerExample {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.incrementAndGet();
}
}
4. synchronized+wait()/notify()
synchronized关键字配合wait()和notify()方法可以实现线程的等待/通知机制。wait()方法可以让一个线程进入等待状态(即使放弃该线程所持有的锁),直到其他线程唤醒它;notify()方法可以唤醒正在等待的某一个线程。
public class WaitNotifyExample {
private Object lock = new Object();
private boolean flag = false;
public void printNumber() {
synchronized (lock) {
while (!flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("1");
flag = false;
lock.notify();
}
}
public void printLetter() {
synchronized (lock) {
while (flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("A");
flag = true;
lock.notify();
}
}
}
5. CyclicBarrier类
CyclicBarrier是JDK提供的一个同步工具类,它可以等待指定数量的线程到达屏障(barrier),然后再同时执行。CyclicBarrier的作用类似于CountDownLatch,但它的计数器可以重复使用。
public class CyclicBarrierExample {
private CyclicBarrier barrier = new CyclicBarrier(4, () -> {
System.out.println("所有线程均已到达屏障,开始执行任务...");
});
public void run() {
System.out.println(Thread.currentThread().getName() + " 已经到达屏障...");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
示例说明
示例一:使用synchronized关键字实现多线程同步
假设有一个计数器类Counter,需要实现多线程对计数器进行操作。使用synchronized关键字实现线程的同步。
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class SynchronizedExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
}
示例二:使用ReentrantLock类实现多线程同步
假设有一个计数器类Counter,需要实现多线程对计数器进行操作。使用ReentrantLock类实现线程的同步。
public class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
public class ReentrantLockExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
counter.increment();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(counter.getCount());
}
}
以上就是详细讲解“Java实现多线程同步五种方法”的完整攻略,希望能对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现多线程同步五种方法详解 - Python技术站