我正在进入java多线程,并决定解决一个更复杂的问题,但到目前为止收效甚微。
我有一个工人生产线,他们会尝试从列表中获取工作(创建产品):
使用notify-wait:
解决了对工作列表的并发访问public class ProductionRequestQueue extends LinkedList<ProductionRequest> {
public ProductionRequestQueue() {
}
public synchronized void push(ProductionRequest productionRequest) {
this.add(productionRequest);
notifyAll();
}
public synchronized ProductionRequest pull() {
while (this.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
}
}
return this.removeFirst();
}}
问题是我需要保证对资源的独占访问权限。我有生产线中可用资源的列表,但我需要保证自己访问资源而不是列表。 我的工人做了:
public Product createProduct(ProductionRequest productionRequest) {
Product product = ProductionLine.products.get(productionRequest.getProductId());
product.create();
return product;
}
@Override
public void run() {
ProductionRequest productionRequest;
while (!productionRequestQueue.isEmpty()) {
productionRequest = productionRequestQueue.pull();
createProduct(productionRequest);
System.out.println(productionRequest + " is being manufactured by " + this);
}
}
然后我有一个将资源与时间联系起来的类,它通过休眠线程来模拟生产过程:
public ResourceTime(Resource resource, int time) {
this.resource = resource;
this.time = time;
}
public void execute() {
synchronized (this.resource) {
Thread thread = new Thread(this);
thread.start();
}
}
@Override
public void run() {
try {
System.out.println(toString());
Thread.sleep(Integer.valueOf(time));
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我认为同步块可以保证对资源的独占访问,但我不断获得空指针异常:
Exception in thread "pool-1-thread-2" java.lang.NullPointerException
at production_line_sim.models.Worker.createProduct(Worker.java:14)
Any thoughts about this?
另外,我如何证明synchronized块保证对每个资源的独占访问? 我认为这种解决方案可能会导致一些线程可能无法访问资源,并且可能需要某种公平算法,有人可以指出我如何做到这一点吗?
答案 0 :(得分:3)
首先,我想强调@ pvg的建议:
实际上,您最好不要使用标准库。概念是更高层次的,而且这些东西都有效。从基元重新实现这些和/或直接使用基元通常是错误的。如果你想获得一个理解,java.util.concurrent的源代码是可用的,Doug Lea的书仍然是一个有用的参考。
你说你已经解决了NPE问题。
另外,我如何证明synchronized块保证对每个资源的独占访问?
synchronized块将为您提供使用等效块的线程之间的独占访问权限。但是,如果您的代码库包含任何代码,该代码在该资源上使用Resource
的synchronized
实例,则存在非独占访问的风险,竞争条件和记忆异常。
您如何找到这样的代码(违反规则)?
我认为这种解决方案可能导致某些线程可能无法访问资源的情况,并且可能需要某种公平算法,有人可以指出我如何做到这一点吗?
公平始终是一个潜在的问题,但通常我们会忽略它。
一个更真实的问题......你不能忽视......是僵局。在您的情况下,考虑您需要2个或更多资源&#34;创造一个&#34;产品&#34;。假设你有两个工人A和B,它们执行以下操作:
Worker A: synchronize R1
Worker A: synchronize R2
Worker B: synchronize R2
Worker B: synchronize R1
如果这两个序列同时发生,你最终可能会有A等待B释放R2而B等待A释放R1。
有解决这个问题的策略: