目录
简单演示
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo01 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
//模拟3个线程
Demo01Thread threadA = new Demo01Thread(lock);
Demo01Thread threadB = new Demo01Thread(lock);
Demo01Thread threadC = new Demo01Thread(lock);
//设置名称
threadA.setName("线程A");
threadB.setName("线程B");
threadC.setName("线程C");
//启动
threadA.start();
threadB.start();
threadC.start();
}
}
class Demo01Thread extends Thread{
private Lock lock;
//通过构造方法传递锁对象
public Demo01Thread(Lock lock){
this.lock = lock;
}
@Override
public void run() {
//加上锁
lock.lock();
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+" :---:"+i);
}
//解开锁
lock.unlock();
}
}
运行结果
synchronized 进行同步互斥控制
import lombok.SneakyThrows;
/**
* synchronized 进行同步互斥控制
* @author layman
* @date 2021/2/9
*/
public class Demo02 {
public static void main(String[] args) {
Demo02Service service = new Demo02Service();
Demo02ThreadA threadA = new Demo02ThreadA(service);
Demo02ThreadB threadB = new Demo02ThreadB(service);
threadA.setName("线程A");
threadB.setName("线程B");
threadA.start();
threadB.start();
}
}
class Demo02Service{
public synchronized void methodA() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+" 开始执行methodA方法:"+System.currentTimeMillis());
Thread.sleep(3000L);
System.out.println(Thread.currentThread().getName()+" 结束执行methodA方法:"+System.currentTimeMillis());
}
public synchronized void methodB() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+" 开始执行methodB方法:"+System.currentTimeMillis());
Thread.sleep(3000L);
System.out.println(Thread.currentThread().getName()+" 结束执行methodB方法:"+System.currentTimeMillis());
}
}
class Demo02ThreadA extends Thread{
private Demo02Service service;
public Demo02ThreadA(Demo02Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.methodA();
}
}
class Demo02ThreadB extends Thread{
private Demo02Service service;
public Demo02ThreadB(Demo02Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.methodB();
}
}
运行结果
修改为ReentrantLock进行同步互斥
public class Demo02 {
public static void main(String[] args) {
Demo02Service service = new Demo02Service();
Demo02ThreadA threadA = new Demo02ThreadA(service);
Demo02ThreadB threadB = new Demo02ThreadB(service);
threadA.setName("线程A");
threadB.setName("线程B");
threadA.start();
threadB.start();
}
}
class Demo02Service{
private SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
private Lock lock = new ReentrantLock();
public /*synchronized*/ void methodA() throws InterruptedException {
lock.lock();
System.out.println(Thread.currentThread().getName()+" 开始执行methodA方法:"+sdf.format(new Date(System.currentTimeMillis())));
Thread.sleep(3000L);
System.out.println(Thread.currentThread().getName()+" 结束执行methodA方法:"+sdf.format(new Date(System.currentTimeMillis())));
lock.unlock();
}
public /*synchronized*/ void methodB() throws InterruptedException {
lock.lock();
System.out.println(Thread.currentThread().getName()+" 开始执行methodB方法:"+sdf.format(new Date(System.currentTimeMillis())));
Thread.sleep(3000L);
System.out.println(Thread.currentThread().getName()+" 结束执行methodB方法:"+sdf.format(new Date(System.currentTimeMillis())));
lock.unlock();
}
}
class Demo02ThreadA extends Thread{
private Demo02Service service;
public Demo02ThreadA(Demo02Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.methodA();
}
}
class Demo02ThreadB extends Thread{
private Demo02Service service;
public Demo02ThreadB(Demo02Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.methodB();
}
}
运行结果
结论
- 调用lock方法的线程会持有对象锁,其他线程只能等待锁被释放(unlock方法)才可以再次争抢锁。
- lock和synchronized一样,都是顺序进行
ReentrantLock与condition实现wait和notify
import lombok.SneakyThrows;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo03 {
public static void main(String[] args) throws InterruptedException {
Demo03Service service = new Demo03Service();
Demo03Thread t = new Demo03Thread(service);
t.start();
Thread.sleep(2000L);
service.signal();
}
}
class Demo03Service{
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
//等待方法
public void await() throws InterruptedException {
lock.lock();
System.out.println("await方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
//该方法需在同步代码块中执行,否则会抛出IllegalMonitorStateException
condition.await();
System.out.println("await方法结束于:" + sdf.format(new Date(System.currentTimeMillis())));
lock.unlock();
}
//通知方法
public void signal() {
lock.lock();
System.out.println("signal方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
condition.signal();
lock.unlock();
}
}
class Demo03Thread extends Thread{
private Demo03Service service;
public Demo03Thread(Demo03Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.await();
}
}
ReentrantLock与condition实现选择性唤醒
import lombok.SneakyThrows;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo04 {
public static void main(String[] args) throws InterruptedException {
Demo04Service service = new Demo04Service();
Demo04ThreadA threadA = new Demo04ThreadA(service);
//A进入等待状态
threadA.start();
Demo04ThreadB threadB = new Demo04ThreadB(service);
//B进入等待状态
threadB.start();
Thread.sleep(3000L);
//只唤醒A
service.signal_A();
}
}
class Demo04Service{
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
//等待方法A
public void awaitA() throws InterruptedException {
lock.lock();
System.out.println("awaitA方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
conditionA.await();
System.out.println("awaitA方法结束于:" + sdf.format(new Date(System.currentTimeMillis())));
lock.unlock();
}
//等待方法B
public void awaitB() throws InterruptedException {
lock.lock();
System.out.println("awaitB方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
conditionB.await();
System.out.println("awaitB方法结束于:" + sdf.format(new Date(System.currentTimeMillis())));
lock.unlock();
}
//通知方法A
public void signal_A() {
lock.lock();
System.out.println("signal_A方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
//唤醒A
conditionA.signal();
lock.unlock();
}
//通知方法B
public void signal_B() {
lock.lock();
System.out.println("signal_B方法开始于:" + sdf.format(new Date(System.currentTimeMillis())));
//唤醒B
conditionB.signal();
lock.unlock();
}
}
class Demo04ThreadA extends Thread{
private Demo04Service service;
public Demo04ThreadA(Demo04Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.awaitA();
}
}
class Demo04ThreadB extends Thread{
private Demo04Service service;
public Demo04ThreadB(Demo04Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
service.awaitB();
}
}
运行结果
结论
ReentrantLock与condition实现生产者与消费者
生产者与消费者(一对一&多对多)
import lombok.SneakyThrows;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 演示一对一和多对多
* @author layman
*/
public class Demo05 {
public static void main(String[] args) {
Demo05Service service = new Demo05Service();
//生产-消费(一对一关系)
/*Demo05Producer producer = new Demo05Producer(service);
Demo05Consumer consumer = new Demo05Consumer(service);
producer.start();
consumer.start();*/
生产-消费(多对多关系)
int size = 5;
Demo05Producer[] producers = new Demo05Producer[size];
Demo05Consumer[] consumers = new Demo05Consumer[size];
for (int i = 0; i < size; i++) {
char name = (char)('A'+i);
producers[i] = new Demo05Producer(service);
producers[i].setName("生产者"+name);
producers[i].start();
consumers[i] = new Demo05Consumer(service);
consumers[i].setName("消费者"+name);
consumers[i].start();
}
}
}
class Demo05Service{
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private String value = "";
public void setValue() throws InterruptedException {
lock.lock();
while(!"".equals(value)){
//如果有值,就等待消费
System.out.println(Thread.currentThread().getName()+" 进入等待状态 ");
condition.await();
}
//如果没有值,就生产值,然后通知消费者消费
value = System.currentTimeMillis()+" - "+System.nanoTime();
System.out.println(Thread.currentThread().getName()+" 生产的值: " + value);
//Thread.sleep(500L);
//condition.signal();
//多生产者与多消费者模式需要唤醒所有等待的线程,否则会唤醒消费者,进入无限等待状态
condition.signalAll();
lock.unlock();
}
public void getValue() throws InterruptedException {
lock.lock();
while(!"".equals(value)){
//如果有值,就消费,然后通知生产者生产
System.out.println(Thread.currentThread().getName()+" 消费的值: " + value);
value = "";
//Thread.sleep(500L);
//condition.signal();
//多生产者与多消费者模式需要唤醒所有等待的线程,否则会唤醒消费者,进入无限等待状态
condition.signalAll();
}
//如果没有值,就等待生产者生产值
System.out.println(Thread.currentThread().getName()+" 进入等待状态 ");
condition.await();
lock.unlock();
}
}
class Demo05Producer extends Thread{
private Demo05Service service;
public Demo05Producer(Demo05Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
while(true){
service.setValue();
}
}
}
class Demo05Consumer extends Thread{
private Demo05Service service;
public Demo05Consumer(Demo05Service service){
this.service = service;
}
@SneakyThrows
@Override
public void run() {
while(true){
service.getValue();
}
}
}
ReentrantLock之公平锁和非公平锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author layman
* @date 2021/2/9
*/
public class Demo06 {
public static void main(String[] args) {
Demo06Service service = new Demo06Service(true);
int size = 20;
Demo06Thread[] threads = new Demo06Thread[size];
for (int i = 0; i < size; i++) {
threads[i] = new Demo06Thread(service);
}
for (int i = 0; i < size; i++) {
threads[i].start();
}
}
}
class Demo06Service{
private Lock lock;
public Demo06Service(boolean isFair){
//true的ReentrantLock是公平锁,反之为非公平锁
this.lock = new ReentrantLock(isFair);
}
public void doSomething(){
lock.lock();
System.out.println(Thread.currentThread().getName()+" 被锁定了");
lock.unlock();
}
}
class Demo06Thread extends Thread{
private Demo06Service service;
public Demo06Thread(Demo06Service service){
this.service = service;
}
@Override
public void run() {
service.doSomething();
}
}