小知識:linkedList.poll()方法:在此鏈表中先獲取到此屬性,再將該屬性刪除.
生產(chǎn)者和消費者線程的分析:在一個長度為10的容量池中,有兩個隊列對容量池進行操作,A隊列負責(zé)往容量池中添加屬性,B隊列負責(zé)將容量池中的屬性刪除掉.此時要考慮的問題:
1.當(dāng)容量池中的屬性數(shù)量大于10的時候,那么此時A隊列就不能添加屬性,此時A隊列必須等待:B隊列消費容量池中的屬性后A隊列才可以對容量池進行繼續(xù)添加;當(dāng)容量池中的屬性值個數(shù)為0的時候,B隊列必須進入等待:A隊列生產(chǎn)出屬性后,B隊列才能夠繼續(xù)消費. 這個就要用到線程的
wait()
和notify()
方法,調(diào)用等待對不能進行操作的線程阻塞,當(dāng)生產(chǎn)完成后,調(diào)用通知方法對等待的線程進行通知,確保阻塞的線程能夠繼續(xù)執(zhí)行.
2.在A隊列生產(chǎn)資源的時候,B隊列此時不能使用,只有當(dāng)資源全部生產(chǎn)完成后,B隊列才能夠使用資源.這個要用到synchronized
關(guān)鍵字對當(dāng)前的生產(chǎn)對象加鎖.
下面一個簡單的生產(chǎn)者消費者實例:
生產(chǎn)者
public class Producer implements Runnable {
private EventStorage storge;
public Producer(EventStorage storage) {
this.storge = storage;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
storge.set();
}
}
}
消費者
public class Consumer implements Runnable {
private EventStorage storage;
public Consumer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
storage.get();
}
}
}
事件存儲消費
public class EventStorage {
private int maxSize;
private List<String> storage;
public EventStorage() {
maxSize = 10;
storage = new LinkedList<String>();
}
public synchronized void set() {
while (storage.size() == maxSize) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.add(UUID.randomUUID().toString());
System.out.println(storage.size());
notifyAll();
}
public synchronized void get() {
while (storage.size() == 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(((LinkedList<?>) storage).poll());
notifyAll();
}
public int getMaxSize() {
return maxSize;
}
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
public List<String> getStorage() {
return storage;
}
public void setStorage(List<String> storage) {
this.storage = storage;
}
}
測試
public static void main(String[] args) {
EventStorage storage = new EventStorage();
Producer producer = new Producer(storage);
Thread thread1 = new Thread(producer);
Consumer consumer = new Consumer(storage);
Thread thread2 = new Thread(consumer);
thread2.start();
thread1.start();
}