java – 将无状态回调放入BlockingQueue是否安全?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 将无状态回调放入BlockingQueue是否安全?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1852字,纯文字阅读大概需要3分钟。
内容图文
我有以下非常简单的回调接口和POJO类:
public interface Action{
public void doAction();
}
public class Person{
private String name;
private String address;
//...etc
//GET, SET, toString
}
我将按如下方式使用它:
public class ActionExecutor{
private static final Logger logger = LogManager.getLogger(ActionExecutor.class);
private final BlockingQueue<Action> blockingQueue = new LinkedBlockingQueue(2000);
public void execute(final Person p){
//modify state of p in some way
blockingQueue.put(new Action(){
public void doAction(){
logger.info("Execution started: " +p.toString );
//do some other job
});
}
}
这里的BlockingQueue用于实现生产者 – 消费者.
问题:是否保证从BlockingQueue采取操作的消费者线程会写出正确的日志消息?即它观察到一个正确的人状态?但我并不十分确定.
我认为不,它不能保证,因为在生产者进行的修改和生产者阅读之间没有发生任何顺序.
解决方法:
答案是,这取决于.
如果您之后从未修改过Person实例,则可以保证.如in the docs所述,存在一种发生在之前的关系:
Memory consistency effects: As with other concurrent collections,
actions in a thread prior to placing an object into a BlockingQueue
happen-before actions subsequent to the access or removal of that
element from the BlockingQueue in another thread.
但是,我仍然不会这样做.如果在将回调放入队列后修改了Person实例,则无法保证.您可以说记录器保证打印的状态至少与添加到队列时的状态一样.
所以消费者会看到这些修改:
public void execute(final Person p){
//modify state of p in some way
blockingQueue.put(new Action(){
但不是那之后的那些.并且因为你在将它传递给新的Action()对象后继续使用p,我会避免这种情况.相反,我会做这样的事情:
public void execute(final Person p){
//modify state of p in some way
blockingQueue.put(new Action() {
final String executionName = p.toString();
public void doAction(){
logger.info("Execution started: " + executionName);
//do some other job
});
}
现在状态被捕获在最终变量中.无论当时的状态是什么,消费者都会看到这个价值.
内容总结
以上是互联网集市为您收集整理的java – 将无状态回调放入BlockingQueue是否安全?全部内容,希望文章能够帮你解决java – 将无状态回调放入BlockingQueue是否安全?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。