我試圖做這樣的事情:同步和線程工作不正常
有是有一個名爲n
和兩個方法put()
和get()
字段,設置n的值或檢索值類Q
n。然後有兩個類Producer
和Consumer
。 Producer
類有一個線程調用put
和consumer
類有一個線程調用get
。我試圖用Object lock
這是Singleton類的唯一實例LockClass.
所以要進行同步,這是我的班問:
public class Q {
int n;
public void put(int n){
System.out.println("Put " + n);
this.n = n;
}
public int get(){
System.out.println("Got " + n);
return n;
}
}
LockClass:
public class LockClass {
private static Object Lock = new Object();
private LockClass(){
}
public static Object getLock(){
return Lock;
}
}
消費者:
public class Consumer implements Runnable {
Thread t;
Q q;
public Consumer(Q q){
this.q = q;
t = new Thread(this);
t.start();
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized(LockClass.getLock()){
q.get();
}
try {
System.out.println("Consumer slept");
Thread.sleep(1000);
System.out.println("Consumer awake");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
生產者:
public class Producer implements Runnable {
Q q;
Thread t;
int i;
public Producer(Q q){
this.q = q;
t = new Thread(this);
t.start();
i = 0;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
i++;
synchronized(LockClass.getLock()){
q.put(i);
}
try {
System.out.println("Producer slept");
Thread.sleep(1000);
System.out.println("Producer awake");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
DemoClass:這個類的主要功能
public class DemoClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Q q = new Q();
Producer prod = new Producer(q);
Consumer cons = new Consumer(q);
}
}
所以,當我運行這個上面的代碼中,我得到的是這樣的:
Put 1
Producer slept
Got 1
Consumer slept
Consumer awake
Producer awake
Got 1
Consumer slept
Put 2
Producer slept
Consumer awake
Producer awake
Got 2
Consumer slept
Put 3
Producer slept
Consumer awake
Producer awake
Got 3
Consumer slept
Put 4
Producer slept
所以,我其實做的線程在生產者和消費者中睡眠,以便有足夠的時間進行上下文切換。現在,當兩個人都需要同時睡覺的時候,如果製片人先睡,它應該首先醒來。但正如我在輸出中看到的那樣,製片人首先睡覺,但仍然是消費者首先醒來,並且無論哪個線程首先被喚醒,都應該獲得鎖定,並且另一個線程應該等待鎖定被釋放。
爲什麼它不按我期待的方式工作?我錯過了什麼嗎?
每當你聽到「生產者」和「消費者」,你應該考慮的是'BlockingQueue'的第一件事。生產者將對象循環放入隊列中(在這種情況下對象可以是'Integer'對象),並且消費者循環取出對象。如果消費者嘗試刪除對象時隊列爲空,則消費者將被阻止,直到對象變爲可用。而且,如果隊列具有較高的大小限制(通常是一個好主意),那麼只要隊列變滿,生產者就會被阻塞。 –
@jameslarge:非常感謝! :)將研究一個BlockingQueue –