1、ReentrantLock
public class LockTest {
static Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
Lock lock = new ReentrantLock();
private void testReentrantLock() {
try {
lock.lock();
} catch (Throwable e) {
} finally {
lock.unlock();
}
}
2、CountDownLatch
private static void testCountDownLatch() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
Thread thread = new Thread(() -> {
System.out.println("1111");
countDownLatch.countDown();
}, "12345678");
Thread thread2 = new Thread(() -> {
System.out.println("22222");
countDownLatch.countDown();
}, "2345678");
thread2.start();
thread.start();
countDownLatch.await();
System.out.println("123456789");
}
3、CyclicBarrier
private static void testCyclicBarrier() {
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
Set<String> set = map.keySet();
System.out.println(set.size());
//Set<Map.Entry<String,Integer>> entrySet=map.entrySet();
// for(Map.Entry<String,Integer> a:entrySet){
// System.out.println(a.getKey());
// System.out.println(a.getValue());
// }
});
for (int i = 0; i < 100; i++) {
new Thread(() -> {
try {
map.put(Thread.currentThread().getName(), 12345);
cyclicBarrier.await();
map.put(Thread.currentThread().getName(), 12345);
//barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
// System.out.println("123456789");
}
4、Phaser
创建了一个Phaser实例并初始注册了3个线程以及主线程,每个线程都执行三个阶段的任务,每个阶段任务之间都通过phaser.arriveAndAwaitAdvance()方法进行同步,每个线程在完成当前阶段的任务后,都会在这个方法上阻塞,直到所有其他线程也完成了它们当前阶段的任务,在所有线程都完成最后一个阶段的任务后,Phaser会自动进入终止状态,此时不会再有线程被阻塞。
public class PhaserExample {
public static void main(String[] args) throws InterruptedException {
// 创建一个Phaser实例,初始时注册3个线程(不包括主线程)
Phaser phaser = new Phaser(3);
// 创建并启动3个线程
for (int i = 0; i < 3; i++) {
int threadNum = i + 1; // 为了在输出中区分线程
new Thread(() -> {
System.out.println("线程" + threadNum + ":已经准备好,等待其他线程。");
// 线程在此等待,直到所有线程都到达这个屏障点
phaser.arriveAndAwaitAdvance();
System.out.println("线程" + threadNum + ":第一阶段任务完成。");
// 模拟第二阶段的任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
// 再次到达屏障点,等待其他线程
phaser.arriveAndAwaitAdvance();
System.out.println("线程" + threadNum + ":第二阶段任务完成。");
// 模拟第三阶段的任务
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
// 最后一次到达屏障点,所有线程都完成后Phaser将自动进入终止状态
phaser.arriveAndAwaitAdvance();
System.out.println("线程" + threadNum + ":第三阶段任务完成,Phaser任务结束。");
}).start();
}
// 等待所有线程完成任务
// 注意:在实际应用中,可能不希望主线程在这里阻塞,而是去做其他工作
// 但为了演示目的,让主线程等待所有工作线程完成
phaser.awaitAdvance(phaser.getPhase());
System.out.println("所有线程的第一阶段任务完成。");
phaser.awaitAdvance(phaser.getPhase() + 1);
System.out.println("所有线程的第二阶段任务完成。");
phaser.awaitAdvance(phaser.getPhase() + 1);
System.out.println("所有线程的第三阶段任务完成,整个任务结束。");
}
}
private static void testPhaser() {
Phaser phaser = new Phaser(2);
Thread thread = new Thread(() -> {
System.out.println("1111");
phaser.arrive();
}, "12345678");
Thread thread2 = new Thread(() -> {
System.out.println("22222");
phaser.arrive();
}, "2345678");
thread2.start();
thread.start();
phaser.awaitAdvance(phaser.getPhase());
System.out.println("123456789");
}
private static void testPhaser2() {
CountDownLatch countDownLatch = new CountDownLatch(1);
Phaser phaser = new Phaser(5);
for (int i = 0; i < 100; i++) {
new Thread(() -> {
if (map.size() == 5) {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
map.put(Thread.currentThread().getName(), 1234);
System.out.println("111111111");
phaser.arriveAndAwaitAdvance();
System.out.println("=========");
if (map.size() == 5) {
countDownLatch.countDown();
}
}).start();
}
}
5、ReadWriteLock
private static void testReadWriteLock() {
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
Lock readLock = readWriteLock.readLock();
Lock writeLock = readWriteLock.writeLock();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
readLock.lock();
System.out.println("read start");
System.out.println("read end");
readLock.unlock();
}, "read").start();
}
for (int i = 0; i < 5; i++) {
new Thread(() -> {
writeLock.lock();
System.out.println("write start");
System.out.println("write end");
writeLock.unlock();
}, "write").start();
}
}
6、Semaphore
Semaphore(信号量)是一个用于控制同时访问特定资源的线程数量的同步工具。它通过维护一个许可集来管理对资源的访问。线程在访问资源之前必须从信号量中获取许可,访问完成后释放许可。如果没有可用的许可,线程将被阻塞,直到有可用的许可为止。
private static void testSemaphore() {
Semaphore semaphore = new Semaphore(2, true);
for (int i = 0; i < 5; i++) {
new Thread(() -> {
try {
//获取许可
semaphore.acquire();
System.out.println("1111111111");
TimeUnit.SECONDS.sleep(1);
System.out.println("==========");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放许可
semaphore.release();
}
}, "write").start();
}
}
7、Exchanger
Exchanger是一个用于线程间数据交换的同步点。它允许两个线程在一个点上交换彼此的数据。每个线程在调用exchange方法时提供一个对象,然后等待另一个线程到达该点进行交换。一旦两个线程都到达交换点,它们就可以安全地交换数据并继续执行。
private static void testExchanger() {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
String a = "a";
try {
System.out.println(Thread.currentThread().getName() + " " + a);
a = exchanger.exchange(a);
System.out.println(Thread.currentThread().getName() + " " + a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "read").start();
new Thread(() -> {
String a = "b";
try {
System.out.println(Thread.currentThread().getName() + " " + a);
a = exchanger.exchange(a);
System.out.println(Thread.currentThread().getName() + " " + a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "write").start();
}
8、LockSupport
LockSupport的主要作用是允许线程进行阻塞和唤醒,而且可以在任意位置对线程进行操作,而无需持有特定的锁。它提供了park()和unpark()两个静态方法,可以分别用于阻塞线程和唤醒线程。
private static void testLockSupport() {
Thread a =new Thread(() -> {
System.out.println("1111");
//阻塞
LockSupport.park();
System.out.println("2222");
}, "123");
a.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread b =new Thread(() -> {
System.out.println("3333");
//释放
LockSupport.unpark(a);
System.out.println("4444");
}, "1234");
b.start();
}
测试方法
public static void main(String[] args) throws InterruptedException {
//testCountDownLatch();
//testCyclicBarrier();
//testPhaser();
//testPhaser2();
//testReadWriteLock();
//testSemaphore();
//testExchanger();
//testLockSupport();
testLockSupport();
}
}