一、ReentrantLock:
ReentrantLock 可以替代 synchronized 其相对 synchronized 来说会更加灵活,
简单看一下写法
public void reentrantLock() {
Lock lock = new ReentrantLock(); // implements Lock
try {
lock.lock(); //等同于 synchronized(this)
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock(); // 务必在最后手动解锁,否则将造成死锁
}
}
ReentrantLock 支持 "尝试加锁" 的操作:
public void tryLock() {
Lock lock = new ReentrantLock();
boolean locked = false;
try {
//尝试加锁,如果加不上则退出加锁操作,程序继续执行
locked = lock.tryLock(2, TimeUnit.SECONDS);
System.out.println(locked);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (locked) lock.unlock();
}
}
ReentrantLock 支持被 "打断"
public static void main(String[] args) {
Lock lock2 = new ReentrantLock();
Thread t2 = new Thread(() -> {
try {
lock2.lockInterruptibly(); //可以对interrupt()方法做出响应
System.out.println("t2 start");
TimeUnit.SECONDS.sleep(5);
System.out.println("t2 end");
} catch (InterruptedException e) {
System.out.println("被打断");
} finally {
lock2.unlock();
}
});
t2.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.interrupt(); //打断线程2的等待
}
ReentrantLock 的公平锁
//参数为true表示为公平锁,请对比输出结果
ReentrantLock lock = new ReentrantLock(true);
二、CountDownLatch (门闩)
public static void main(String[] args) {
Thread[] threads = new Thread[10];
CountDownLatch countDownLatch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
int x = 0;
for (int j = 0; j < 10000; j++) x += j;
countDownLatch.countDown(); // 递减
});
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
try {
countDownLatch.await(); // 等待锁全部结束
} catch (InterruptedException e) {
e.printStackTrace();
}
// 全部结束之后输出
System.out.println("end latch");
}
三、CyclicBarrier (满了在做)
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println("do some thing"));
for (int i = 0; i < 100; i++) {
new Thread(() -> {
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
四、读写锁
- 其优势是读操作可以同时进行
static Lock lock = new ReentrantLock();
private static int value;
static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static Lock readLock = readWriteLock.readLock();
static Lock writeLock = readWriteLock.writeLock();
public static void read(Lock lock) {
try {
lock.lock();
Thread.sleep(1000);
System.out.println("read over!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void write(Lock lock, int v) {
try {
lock.lock();
Thread.sleep(1000);
value = v;
System.out.println("write over!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Runnable readR = ()-> read(readLock);
Runnable writeR = ()->write(writeLock, new Random().nextInt());
for(int i=0; i<18; i++) new Thread(readR).start();
for(int i=0; i<2; i++) new Thread(writeR).start();
}
五、Semaphore (限流)
设定允许执行的线程个数
public static void main(String[] args) {
Semaphore s = new Semaphore(1, true);
new Thread(()->{
try {
s.acquire();
System.out.println("111111");
Thread.sleep(200);
System.out.println("1111111");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
s.release();
}
}).start();
new Thread(()->{
try {
s.acquire();
System.out.println("2222222");
Thread.sleep(200);
System.out.println("2222222");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
六、Phaser (阶段锁)
- 所有人到达同一阶段后才能执行下一步骤
static Random r = new Random();
static MarriagePhaser phaser = new MarriagePhaser();
static void milliSleep(int milli) {
try {
TimeUnit.MILLISECONDS.sleep(milli);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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 MarriagePhaser 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;
default:
return true;
}
}
}
static class Person implements Runnable {
String name;
public Person(String name) {
this.name = name;
}
public void arrive() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 到达现场!\n", name);
phaser.arriveAndAwaitAdvance();
}
public void eat() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 吃完!\n", name);
phaser.arriveAndAwaitAdvance();
}
public void leave() {
milliSleep(r.nextInt(1000));
System.out.printf("%s 离开!\n", name);
phaser.arriveAndAwaitAdvance();
}
private void hug() {
if(name.equals("新郎") || name.equals("新娘")) {
milliSleep(r.nextInt(1000));
System.out.printf("%s 洞房!\n", name);
phaser.arriveAndAwaitAdvance();
} else {
phaser.arriveAndDeregister();
}
}
@Override
public void run() {
arrive();
eat();
leave();
hug();
}
}
七、Exchanger (交换)
static Exchanger<String> exchanger = new Exchanger<>();
public static void main(String[] args) {
new Thread(() -> {
String s = "T1";
try {
s = exchanger.exchange(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + s);
}, "t1").start();
new Thread(() -> {
String s = "T2";
try {
s = exchanger.exchange(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + s);
}, "t2").start();
}