【JavaEE】JUC的常见类

目录

Callable接口

ReentrantLock

用法

[ReentrantLock与 synchronized的区别](#ReentrantLock与 synchronized的区别)

信号量Semaphore

CountDownLatch

CountDownLatch的两个主要方法


JUC全称java.util.concurrent,这个包里的内容主要就是跟多线程有关的组件。

Callable接口

Callable也是一种创建线程的方式,适合于想让某个线程执行一个逻辑,并返回结果的时候,相比之下,Runable不关注结果

Callable<Integer> callable=new Callable<Integer>() {

@Override

public Integer call() throws Exception {

return null;

}

}

  • Callable<返回结果的类型>
  • call()是Callable的核心方法,与Runable中的run()一样

完整的示例:

//定义了任务

Callable<Integer> callable=new Callable<Integer>() {

@Override

public Integer call() throws Exception {

int sum = 0;

for (int i = 0; i < 100; i++) {

sum += i;

}

return sum;

}

};

//把任务放到线程中进行执行
FutureTask<Integer> futureTask=new FutureTask<>(callable);

Thread t=new Thread(futureTask);

t.start();

//此处的get就能获取到callable里面的返回结果

//由于线程是并发执行的,执行到主线程get的时候,t线程可能还没有执行完

//没执行完的话,get就会阻塞

System.out.println(futureTask.get());

  • FutureTask用来保存Callable的返回结果

ReentrantLock

ReentrantLock也是一个可重入锁,使用效果和synchronized是类似的;

优势:

  1. ReentrantLock在加锁的时候,有两种方式:lock,tryLock,提供更多的操作空间
  2. ReentrantLock提供了公平锁的实现,默认情况下是非公平锁
  3. ReentrantLock提供了更强大的等待通知机制,搭配了Condition类,实现等待通知

用法

  • lock():加锁,如果获取不到锁就死等
  • trylock():超时时间,加锁,如果获取不到锁,等待一定的时间后,放弃加锁
  • unlock():解锁

ReentrantLock lock=new ReentrantLock();

lock.lock();

try{

}

finally {

lock.unlock();

}

ReentrantLock与 synchronized的区别

  • synchronized是一个关键字,是JVM内部实现的,ReentrantLock是标准库中的一个类,是在JVM外实现的
  • synchronized使用时不需要手动释放锁,ReentrantLock使用时需要手动释放锁
  • synchronized在申请锁失败时,会死等,ReentrantLock可以通过trylock的方式等待一段时间后放弃
  • synchronized是非公平锁,ReentrantLock默认是非公平锁,可以通过构造方法传入一个true开启公平锁模式

信号量Semaphore

信号量,就是一个计数器,描述"可用资源"的个数

  • 申请一个资源,让计数器-1(P操作)
  • 释放一个资源,让计数器+1(V操作)

锁本质上就属于一种特殊的信号量,可以看成可用资源为1的信号量,二元信号量(只有加锁和解锁操作)

Semaphore semaphore=new Semaphore(5);

semaphore.acquire();

System.out.println("P操作");

semaphore.acquire();

System.out.println("P操作");

semaphore.release();

System.out.println("V操作");

CountDownLatch

适用于多个线程完成一系列任务的时候,用来衡量任务的进度是否完成,比如需要把一个大的任务,拆分成多个小的任务,让这些任务并发的去执行,就可以使用CountDownLatch来判定说当前的这些任务是否都完成了。

CountDownLatch的两个主要方法

  • await,调用的时候会阻塞,就会等待其他的线程完成任务,所有的线程完成了任务之后,此时这个await才会继续往下走
  • countDown,通知CountDownLatch,我当前这个子任务已经完成了

//await会在10次调用完countDown之后才能继续执行

CountDownLatch countDownLatch=new CountDownLatch(10);

for(int i=0;i<10;i++)

{

Thread t=new Thread(()->{

int id=i;

System.out.println("thread "+id);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

countDownLatch.countDown();

});

}

countDownLatch.await();

System.out.println("所有任务都完成了");

相关推荐
2602_9599609210 分钟前
大厂Java面试:Spring Boot、JVM、Redis、Kafka与Elasticsearch在内容社区UGC场景下的实战拷问
java·jvm·spring boot·redis·面试题
小新讲网安1 小时前
WiFi安全攻防实战:WPA3新协议与传统破解技术全解析
开发语言·网络·安全·php·漏洞·nmap·漏洞检测
必须会一定会7 小时前
Agent Plugins 1.0实战:plugin.json、skills、mcp.json目录结构与迁移
开发语言·人工智能·ai编程
St_rive7 小时前
Page Object设计模式
java·开发语言·设计模式
wp123_18 小时前
硬件元器件笔记|IPX8 防水 Type‑C 母座安费诺 124018802112A 与 TONEVEE TY48086‑24A 分析
c语言·开发语言·笔记
wuyk5558 小时前
4.树:一对多的层次数据结构
开发语言·数据结构·stm32·单片机
风流 少年8 小时前
Spring AI 2.0:SSE
java·人工智能·spring
凤山老林8 小时前
精细化流量治理:Spring Boot 动态特性开关与灰度发布体系
java·spring boot·后端
luj_17689 小时前
桥牌思维启示:系统设计的模块化架构
c语言·开发语言·c++·经验分享·算法