锁:CountDownLatch闭锁,也叫线程递减锁
CyclicBarrier:栅栏,实现线程之间的同步协调工作
Exchanger:交换机用于两个线程之间进行信息交互
重入锁ReentrantLock:
ReentrantLock rt=newReentrantLock();
默认的机制就是非公平锁机制
如果想变成公平锁机制:ReentrantLockrt=new ReentrantLock(true);
如果要用重入锁,一定要注意锁释放的问题,要放在finally代码块里来做,确保锁不会异常而得不到释放
package lock;
/*
* synchronized 性能低,原因是用的是公平锁的机制来实现的,导致吞吐量很低
*/
public class Student {
public static String name = "李雷";
public static String gender = "男";
public static void main(String[] args) {
new Thread(new read()).start();
new Thread(new write()).start();
}
}
class read implements Runnable{
@Override
public void run() {
while (true) {
System.out.println(Student.name);
System.out.println(Student.gender);
}
}
}
class write implements Runnable{
@Override
public void run() {
while (true) {
synchronized(Student.class){//将要操作的累锁住,不允许别的线程操作
if("李雷".equals(Student.name)){
Student.name="韩梅梅";
Student.gender="女";
}else {
Student.name="李雷";
Student.gender="男";
}
}
}
}
}
package lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReEntrantLockTestDemo {
public static String name = "李雷";
public static String gender = "男";
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
new Thread(new Read(reentrantLock)).start();
new Thread(new Write(reentrantLock)).start();
}
}
class Read implements Runnable{
ReentrantLock reentrantLock;
public Read(ReentrantLock reentrantLock) {
this.reentrantLock = reentrantLock;
}
@Override
public void run() {
while (true) {
reentrantLock.lock();
System.out.println(ReEntrantLockTestDemo.name+":"+ReEntrantLockTestDemo.gender);
reentrantLock.unlock();
}
}
}
class Write implements Runnable{
ReentrantLock reentrantLock;
public Write(ReentrantLock reentrantLock) {
this.reentrantLock = reentrantLock;
}
@Override
public void run() {
while (true) {
reentrantLock.lock();
if("李雷".equals(ReEntrantLockTestDemo.name)){
ReEntrantLockTestDemo.name="韩梅梅";
ReEntrantLockTestDemo.gender="女";
}else {
ReEntrantLockTestDemo.name="李雷";
ReEntrantLockTestDemo.gender="男";
}
reentrantLock.unlock();
}
}
}
package lock;
import java.util.concurrent.CountDownLatch;
/**
* CountDownLatch 闭锁,也叫线程递减锁
*
* 案例:做饭案例
* 买菜和买锅交给两个线程去做
*
* 闭锁使用注意:
* 1.创建闭锁时,计数器要根据线程数量以及业务场景去决定
* 2.多个线程需要用的是同一把闭锁
* 3.await()和countDown的方法使用
* 最大的作用:能够达到线程同步协调效果。利用了阻塞机制来实现的。
* @author zll
*
*/
public class CountdownTestDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(2);
new Thread(new MaiGuo(countDownLatch)).start();
new Thread(new MaiCai(countDownLatch)).start();
//await方法会产生阻塞,当闭锁的初始技术器减到变为0的时候放开
countDownLatch.await();
System.out.println("饭好了");
}
}
class MaiGuo implements Runnable{
CountDownLatch countDownLatch;
public MaiGuo(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
System.out.println("锅买了");
//每调用一次countDown,计数器-1
countDownLatch.countDown();
}
}
class MaiCai implements Runnable{
CountDownLatch countDownLatch;
public MaiCai(CountDownLatch countDownLatch) {
this.countDownLatch=countDownLatch;
}
@Override
public void run() {
System.out.println("菜也买了");
countDownLatch.countDown();
}
}
package lock;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 栅栏,实现线程之间的同步协调工作
* 案例:赛马
* 两匹赛马,必须都要到达栅栏前后,才能开始一起跑。
* 用两个线程代表两匹马
* @author zll
*
*/
public class CyclicTestDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
new Thread(new BaiMa(cyclicBarrier)).start();
new Thread(new HeiMa(cyclicBarrier)).start();
}
}
class BaiMa implements Runnable{
CyclicBarrier cyclicBarrie;
public BaiMa(CyclicBarrier cyclicBarrie) {
this.cyclicBarrie = cyclicBarrie;
}
@Override
public void run() {
System.out.println("白马来到起跑线");
try {
cyclicBarrie.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("白马开始跑~~~~~~~~");
}
}
class HeiMa implements Runnable{
CyclicBarrier cyclicBarrie;
public HeiMa(CyclicBarrier cyclicBarrie) {
this.cyclicBarrie=cyclicBarrie;
}
@Override
public void run() {
System.out.println("黑马闹肚子了");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("黑马来到起跑线");
try {
cyclicBarrie.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("黑马开始跑~~~~~~~~");
}
}
package lock;
import java.util.concurrent.Exchanger;
/**
* 交换机用于两个线程之间进行信息交互
* 案例:两个间谍相互交换暗号
* 用两个线程代表两个间谍
* @author zll
*
*/
public class ExchangerTestDemo{
public static void main(String[] args) {
Exchanger exchanger = new Exchanger();
new Thread(new spy1(exchanger)).start();
new Thread(new spy2(exchanger)).start();
}
}
class spy1 implements Runnable{
Exchanger<String> exchanger;
public spy1(Exchanger exchanger) {
this.exchanger=exchanger;
}
@Override
public void run() {
String string = "回眸一笑";
try {
//exchange用于将信息传递给另外线程
//此外,exchange的返回值是对方线程传来的信息
String exchange = exchanger.exchange(string);
System.out.println("收到spy2的消息是:"+exchange);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class spy2 implements Runnable{
Exchanger<String> exchanger;
public spy2(Exchanger exchanger) {
this.exchanger=exchanger;
}
@Override
public void run() {
String string = "寸草不生";
try {
String exchange = exchanger.exchange(string);
System.out.println("收到是spy1的消息是:"+exchange);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}