首页 新闻 会员 周边

如何确保程序被结束某些处理任务的线程可以处理完才结束

0
悬赏园豆:10 [已解决问题] 解决于 2021-09-15 18:02

例如我有一个记日志的类库,其中设计了,一个单例队列,往里塞日志信息。
用另外一个线程去将日志写到硬盘。
那么这里就会存在一定的延迟,假如引用我这个类库的程序被结束了,如何才能确保写日志的线程处理完所有队列中的日志才结束呢?

Aaxuan的主页 Aaxuan | 初学一级 | 园豆:136
提问于:2021-09-09 16:33
< >
分享
最佳答案
1

那得看你的主线程的程序是怎么结束了,看你的描述我猜测你现在的做法是:你在主线程中处理你的业务逻辑,然后业务逻辑会产生一些日志,然后直接往类库中的队列中发送日志消息,然后你再另起一个子线程来读取队列中的日志数据并写到文件中,然后你担心的问题是:当你的主线程产生的日志数据很快很多时,日志队列会有消息堆积,导致子线程无法第一时间把队列中的日志数据都写到本地,当你主线程所在的程序结束了之后,未写完的日志数据就丢失了。
如果这三者都是在同一个进程,然后你的结束方法是粗暴地杀死进程,那么无论如何你也避免不了的。如果你想数据不丢失,或者影响降到最小,你可以不要异步写日志,而是同步写,即是直接在主线程处理逻辑时就把日志写下来,这样即使你的进程突然挂掉,你丢失的也只是当前正在处理的逻辑的日志。
如果要做异步写,可以考虑把日志的接收和输出做到同一个进程中,主业务逻辑在另一个进程,然后主业务所在的进程直接向日志进程发送消息就行了,即使主业务的进程挂掉了也不会影响日志数据。这也是现在流行的消息队列组件(简称MQ),现在常用的MQ有RabbitMQ、Kafka、RocketMQ等,你可以去了解一下。

收获园豆:10
我是满意吖 | 菜鸟二级 |园豆:386 | 2021-09-09 17:24

是的,你理解了我的问题。我之前一直在想的问题就是在同一个进程中怎么去控制。
我主要是担心同步记录日志会受到硬盘IO阻塞。
理想的办法也就是收日志写日志放到另外的进程去处理。
但有个疑问就是按你的意思讲,一些比较有名的log类库,像nlog他们也是会存在丢一部分日志的问题吗。

Aaxuan | 园豆:136 (初学一级) | 2021-09-15 18:07
其他回答(2)
0

每次从队列取数据,队列没数据了,就可以确认结束了

不知道风往哪儿吹 | 园豆:2035 (老鸟四级) | 2021-09-09 16:51
0

Java
Runtime下有一个函数:
public void addShutdownHook(Thread hook)
注册一个线程,在结束时使用。
可以一试。

快乐的凡人721 | 园豆:3916 (老鸟四级) | 2021-09-09 16:52
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册