V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  git00ll  ›  全部回复第 13 页 / 共 16 页
回复总数  307
1 ... 5  6  7  8  9  10  11  12  13  14 ... 16  
2022-03-10 18:37:00 +08:00
回复了 git00ll 创建的主题 Java 请教大家一个问题,线程池何时清理中断状态的,追源码没找到
@nothingistrue 你发散的太多了,题目问的是 为什么 MyRun 里面设置了中断后,查询中断状态为 true ,MyRun2 中是同一个线程,再查询中断状态却为 false 。

答案是:在线程池的 getTask 方法里,调用 BlockQueue 的 take 方法,抛中断异常后中断状态被清除了,所以 MyRun2 中获取到中断状态为 false 。
2022-03-10 17:29:33 +08:00
回复了 git00ll 创建的主题 Java 请教大家一个问题,线程池何时清理中断状态的,追源码没找到
@nothingistrue 不管怎么理解注释的描述,在 java.util.concurrent.LinkedBlockingQueue#take 方法里。第五行
调用 takeLock.lockInterruptibly();
点进去
```
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}

public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
}

```

可以清楚的看到,会主动检测并清除当前线程的中断标识,如果为中断状态,清除并抛出 InterruptedException 。
主动检测线程的中断标志位,是毫无疑问的。
2022-03-10 16:50:39 +08:00
回复了 git00ll 创建的主题 Java 请教大家一个问题,线程池何时清理中断状态的,追源码没找到
@litchinn
@nothingistrue

自答一下:

首先我们要知道,如果我顺序的执行以下代码,是会抛出中断异常的
```
BlockingQueue<Runnable> queue = getQueue();
Thread.currentThread().interrupt();
queue.take(); //这里抛出中断异常
```
虽然是先设置的中断状态,后执行的堵塞队列的 take()方法,但 take()方法内部会检测当前线程的中断状态。



那单线程池是如何工作的呢?可以认为一个堵塞队列,加一个死循环的线程。线程从队列中获取任务执行,而这个获取的过程就是调用了
BlockQueue 的 take 方法。

所以这就解释了题目的问题,
1. 我们在 MyRun 中将当前线程设为中断状态,MyRun 执行完成后线程处于中断状态。
2. 然后开始从队列中 take 下一个任务,此时就会抛出中断异常,并清除中断状态
3. 线程池抓住中断异常,忽略并继续 take 下一个任务
4. 此时 take 到 MyRun2 任务,并执行它。这样 MyRun2 再检测中断状态就是 false 了


总结就是,线程池在 take 下一个任务时,如果抛出中断异常,会抓住异常并继续 take 下一个任务,而抛出中断异常时中断状态就被清除了。


这一快的源码如下, 正式在 while 循环的条件里,一直调用 getTask() 方法,
```
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;

```

getTask 方法,正是调用了堵塞队列的 take 方法,并忽略了中断异常
```
private Runnable getTask() {
for (;;) {
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
```
2022-03-09 16:07:07 +08:00
回复了 git00ll 创建的主题 Java 请教大家一个问题,线程池何时清理中断状态的,追源码没找到
@qfdk 这个好像不能看出线程的中断状态
2022-03-09 15:59:45 +08:00
回复了 git00ll 创建的主题 Java 请教大家一个问题,线程池何时清理中断状态的,追源码没找到
@cheng6563
@uSy62nMkdH
因为是个单线程的线程池,Myrun 和 Myrun2 其实用的是同一个线程。通过输出的 thread hashcode()也能看出线程是同一个。

Myrun 里面已经将线程设为中断状态了,理论上 Myrun2 运行的时候应该是处于中断状态的,但是却没有。所以一定有一个地方将该线程的状态标识移除了,我没找到在哪里实现的。
2022-03-07 21:31:48 +08:00
回复了 leebs 创建的主题 MongoDB mongodb 数据全量加载到 redis,怎样提升速度?
@wellsc 与哪个版本的 redis 没有关系,因为应用与 redis 网络交互 RTT 的存在,单线程写很难达到 1000 次 /s 。
2022-03-07 20:26:04 +08:00
回复了 leebs 创建的主题 MongoDB mongodb 数据全量加载到 redis,怎样提升速度?
你只能做到 redis 与 db 中的某个瞬间的数据是一致的,不可能保证恰好与导入完成时数据一致。考虑看业务上能否改。
另外 redis 写时,开 20-30 线程一起写会快很多。
h2 可以设置磁盘模式。
本人觉得可以用在生产上
md5 已经很快了。剩下的编写能充分利用多核的代码,服务器增加核心数。
2022-01-18 18:28:37 +08:00
回复了 naoshier 创建的主题 云计算 aws s3 用户上传的文件,如何只允许用户访问
可以使用加签的链接在后端鉴权。但其他用户拿到了加签后的链接,肯定也是可以访问的。
2022-01-11 13:46:16 +08:00
回复了 111qqz 创建的主题 问与答 给女票选生日礼物,有什么建议?
无论买啥,建议再搭配一把鲜花
@chaosrb79 酷安,qq 浏览器评论区 找找看
2022-01-05 18:55:35 +08:00
回复了 lipaa 创建的主题 程序员 讨论下 卡密下发 保证不重发 除了不用 redis 还有啥方案
for update 。简单 暴力。性能也不差
2021-12-28 16:21:51 +08:00
回复了 lianglu 创建的主题 程序员 Java 有什么开源框架值得深入研究?
jackson 也值得看
2021-12-28 16:06:39 +08:00
回复了 lianglu 创建的主题 程序员 Java 有什么开源框架值得深入研究?
netty
project.reactor
openFeign
spring gateway
vertx
2021-12-28 12:50:30 +08:00
回复了 git00ll 创建的主题 Java Project Reactor,如何实现主线程消费报错时停止 Flux 流
@yazinnnn
业务场景里有一些限制,
1. 需要保持输入和输出的顺序一致,
2. 流中的数据从文件中读取的,数据量非常大,无法全部加载到内存。只能边读取边处理。
3.处理过程中其中一条处理错误时,算失败,中断流不再继续。

一方面 stream 的并行流没有拉模式,无法精准控制载入内存的数据行数。
且并行 stream 提供的 api 太少,相比于 reactor 提供的控制选项不足
2021-12-28 10:39:40 +08:00
回复了 git00ll 创建的主题 Java Project Reactor,如何实现主线程消费报错时停止 Flux 流
@yazinnnn 假设 toInt 这个操作是比较耗时的,可以实现将 toInt 放置在多核上运行,最终结果再汇聚到主线程上。
因为主线程上开启了传统注解事务,需要在主线程上操作 Flux 的处理结果
30 分钟是指现实世界中的每 30 分钟作为一个区间吗?
感觉建张表存就可以了,内存里持有当前区间最大值,处理数据时比内存中值大就更新到数据库,否则就跳过。

如果是滚动 30 分钟,可以使用找个时序数据库用一下。
2021-12-25 20:21:04 +08:00
回复了 awanganddong 创建的主题 MySQL mysql 并发操作的问题
for update 没问题的,每秒 4000 次
@dingwen07 好的,我尝试一下关闭现代待机试试,看以后能否复现了
1 ... 5  6  7  8  9  10  11  12  13  14 ... 16  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2239 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 29ms · UTC 16:11 · PVG 00:11 · LAX 08:11 · JFK 11:11
Developed with CodeLauncher
♥ Do have faith in what you're doing.