LongAdder
juc.atomic包下,在很高并发情况下效率比AtomicLong效率要高
原理:在底层是一个分段锁的设计,分成一个线程数组,将线程分别锁定在不同元素中,算出结果后加到一起。分段锁也是CAS。
效率比较:
sync<atomic,无锁乐观锁(sync在小数量小并发未必效率低,锁升级)
atomic<LongAdder,分段锁
ReetrantLock(底层为CAS)
可重入锁:在同一线程内,可反复获得锁
(sync必是可重入的,如果不能重入,子类无法调用父类锁)
加锁解锁
Lock lock = new ReetrantLock();
lock.lock();//加锁
lock.unlock();//解锁(finally)
尝试获得锁
//5秒钟之内获得锁,未获得取消操作
//返回boo值,如果获取到锁返回true
boolean boo = lock.tryLock(5,TimeUnit.SECONDS);
可打断锁
lock.lockInterruptibly();//可以对interrupt进行响应
公平锁
Lock lock = new ReetrantLock(true);//设置为公平锁
CountDownLatch
倒数门闩
CountDownLatch cdl = new CountDownLatch(100);//计数100次
cdl.countDown();//在线程执行完毕后,进行倒数计数-1
cdl.await();//等待,在执行完100次后归零,打开门闩
CyclicBarrier
循环栅栏(限流)
1、复杂操作:
1.数据库
2.网络
3.文件
2、并发执行
CyclicBarrier cb = new CyclicBarrier(20,() -> System.out.println("20已满,发车!") );
cb.await();//等待
Phaser
阶段,栅栏组。可以控制栅栏个数,和栅栏等待线程等待数量
static class MyPhaser extends Phaser {
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase) {
case 0:
System.out.println("第一个方法执行!" + registeredParties);
System.out.println();
return false;
case 1:
System.out.println("第二个方法执行!" + registeredParties);
System.out.println();
return false;
case 2:
System.out.println("第三个方法执行!" + registeredParties);
System.out.println();
return false;
case 3:
System.out.println("第四个方法执行!" + registeredParties);
return true;//返回true所有线程结束
default:
return true;
}
}
}
public static void main(String[] args) {
phaser.bulkRegister(7);//设置栅栏线程个数
for(int i=0; i<5; i++) {
new Thread(new Person("p" + i)).start();
}
new Thread(new Person("新郎")).start();
new Thread(new Person("新娘")).start();
}
static class Person implements Runnable {
String name;
public Person(String name) {
this.name = name;
}
public void arrive() {
System.out.printf(“第一个”);
phaser.arriveAndAwaitAdvance();//到达等待
}
public void eat() {
System.out.printf(“第二个”);
phaser.arriveAndAwaitAdvance();
}
public void leave() {
System.out.printf(“第三个”);
phaser.arriveAndAwaitAdvance();
}
private void hug() {
if(name.equals("1") || name.equals("2")) {
System.out.printf(“第四个”);
phaser.arriveAndAwaitAdvance();
} else {
phaser.arriveAndDeregister();//到达并取消注册
//phaser.register()
}
}
@Override
public void run() {
//按序执行
arrive();
eat();
leave();
hug();
}
}
按照栅栏顺序执行, phaser.arriveAndAwaitAdvance();栅栏等待
ReadWriteLock
读写锁
读锁:共享锁
写锁:排他锁(互斥锁)
ReadWriteLock rwl = new ReentrantReadWriteLock();
Lock readL = rwl.readLock();
Lock writeL = rwl.writeLock();
通过读锁共享,写锁排他,读必须上锁防止写操作进入
Semaphore
信号量(限流,卖票)
//允许一个线程同时执行,第二个参数可传true,公平锁属性
Semaphore s = new Semaphore(1);
s.acquire();//如果信号量不为0,取得信号量锁,该信号量由1变为0
s.release();//释放信号量,该信号量由0恢复为1
Exchanger
交换两个线程的数据。
Exchanger容器会保存数据,当第一个线程调用exchange时,该线程阻塞,将值放到容器中。第二个线程调用exchange时,将该值放到容器中。两个值交换后。继续执行其他线程
Exchanger<String> ex = new Exchanger<>();
String result = ex.exchange(result);//两个线程进行调用,互换数据
LockSupport
LockSupport.park();//线程阻塞
LockSupport.unpark();//线程继续执行,unpack可以在park之前调用