关于java.util.concurrent您不知道的 5 件事,第1部分 - 编程入门网
drop;
List<String> messages = Arrays.asList(
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"Wouldn''t you eat ivy too?");
public Producer(BlockingQueue<String> d) { this.drop = d; }
public void run()
{
try
{
for (String s : messages)
drop.put(s);
drop.put("DONE");
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}
class Consumer
implements Runnable
{
private BlockingQueue<String> drop;
public Consumer(BlockingQueue<String> d) { this.drop = d; }
public void run()
{
try
{
String msg = null;
while (!((msg = drop.take()).equals("DONE")))
System.out.println(msg);
}
catch (InterruptedException intEx)
{
System.out.println("Interrupted! " +
"Last one out, turn out the lights!");
}
}
}
public class ABQApp
{
public static void main(String[] args)
{
BlockingQueue<String> drop = new ArrayBlockingQueue(1, true);
(new Thread(new Producer(drop))).start();
(new Thread(new Consumer(drop))).start();
}
}
ArrayBlockingQueue 还体现了“公平” — 意思是它为读取器和编写器提供线程先入先出 访问。这种替代方法是一个更有效,但又冒穷尽部分线程风险的政策。(即,允许一些读取器 在其他读取器锁定时运行效率更高,但是您可能会有读取器线程的流持续不断的风险,导致编 写器无法进行工作。) 关于java.util.concurrent您不知道的 5 件事,第1部分(3)时间:2012-04-24 IBM Ted Neward注意 Bug! 顺便说一句,如果您注意到 Guarded Blocks 包含一个重大 bug,那么您是对的 — 如果开 发人员在 main() 中的 Drop 实例上同步,会出现什么情况呢? BlockingQueue 还支持接收时间参数的方法,时间参数表明线程在返回信号故障以插入或者 检索有关项之前需要阻塞的时间。这么做会避免非绑定的等待,这对一个生产系统是致命的, 因为一个非绑定的等待会很容易导致需要重启的系统挂起。 4. ConcurrentMap Map 有一个微妙的并发 bug,这个 bug 将许多不知情的 Java 开发人员引入歧途。 ConcurrentMap 是最容易的解决方案。 当一个 Map 被从多个线程访问时,通常使用 containsKey() 或者 get() 来查看给定键是 否在存储键/值对之前出现。但是即使有一个同步的 Map,线程还是可以在这个过程中潜入,然 后夺取对 Map 的控制权。问题是,在对 put() 的调用中,锁在 get() 开始时获取,然后在可 以再次获取锁之前释放。它的结果是个竞争条件:这是两个线程之间的竞争,结果也会因谁先 运行而不同。 如果两个线程几乎同时调用一个方法,两者都会进行测试,调用 put,在处理中丢失第一线 程的值。幸运的是,ConcurrentMap 接口支持许多附加方法,它们设计用于在一个锁下进行两 个任务:putIfAbsent(),例如 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |