java set 线程安全_Java:这种业务逻辑如何做到线程安全呢?

首先解决你的问题:

public class Process implements Runnable {

public static Set set = new HashSet();

public void run() {

synchronized (set) {

// 1、遍历取出set中元素

// 2、具体业务逻辑

// 3、清空set

set.clear();

}

}

public void storage(String str) {

synchronized (set) {

set.add(str);

}

}

}

在以上两个地方加上synchronized (set),由于set是static的,所以只有一个实例,被锁住的代码块可以保证同时只有一个线程能运行进去。也就是在【遍历取出set中元素->具体业务逻辑->清空set】的同时,storage方法中的set.add(str)是要阻塞等待上面的操作执行完成才能add。

需要注意的是,不能使用synchronized (this),因为Process可能会有多个实例(其实根据你给的这些代码我也判断不出是否有多个实例,猜的..)。

最后给你建议一个性能更好的解决方法:使用阻塞队列ArrayBlockingQueue,因为你的问题是一个典型的生产者消费者模型,而且不需要你自己考虑线程安全问题,阻塞队列本身已经帮你解决了。你的现有的程序中,如果消费者(也就是run方法)正在处理任务,生产者(即storage方法)是不能往队列里面添加任务的。而如果使用ArrayBlockingQueue可以一边生产一边消费。

DEMO:

public class Process implements Runnable {

// 使用阻塞队列,队列的默认大小10,可以根据需求调整

public static ArrayBlockingQueue queue = new ArrayBlockingQueue(10);

public void run() {

try {

String task = queue.take(); // 线程安全的方式取一条任务,如果队列为空则阻塞等待直到有新的任务加入进来

process(task); // 处理任务,具体逻辑

} catch (InterruptedException e) {

e.printStackTrace();

}

}

public void storage(String str) {

try {

queue.put(str); // 线程安全的方式加一条任务,如果队列满了则阻塞等待直到消费者取走任务有空间

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

当然以上代码还可以改的模块更清晰可读性更高一点,这里我就不再继续写了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值