У меня недавно была проблема с двумя потоками, зависшими в тупике, потому что они не контролировали один и тот же объект, как я думал, что они были . Как оказалось, реализация шаблона Singleton решила проблему . Но почему?
Я создал только один экземпляр класса, для которого объект был частной собственностью, поэтому я ожидал, что он все равно будет одноэлементным.
Для полноты вопроса приведем также код, иллюстрирующий разницу:
До внедрения шаблона Singleton:
class Worker {
private BlockingQueue q = new LinkedBlockingQueue();
public void consume(String s) {
// Called by thread 1.
// Waits until there is anything in the queue, then consumes it
}
public void produce(String s) {
// Called by thread 2.
// Puts an object in the queue.
}
// Actually implements Runnable, so there's a run() method here too...
}
Темы были начаты так:
Worker w = new Worker();
new Thread(w).start();
// Producer also implements Runnable. It calls produce on its worker.
Producer p = new Producer(w);
new Thread(p).start();
Теперь, когда я исследовал очереди, которые фактически использовались в produce()
и consume()
, System.identityHashCode(q)
дал разные результаты в разных потоках.
С одиночным рисунком:
class Worker {
private static BlockingQueue q;
private BlockingQueue getQueue() {
if(q == null) {
q = new LinkedBlockingQueue();
}
return q;
}
// The rest is unchanged...
}
Вдруг это работает. Почему этот шаблон необходим здесь?