生產者,消費者,固定長度緩衝區,此外外部可以中斷線程
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import javax.swing.*;
public class ProducerConsumer {
public static JFrame inst;
public static void main(String[] args) {
BufferLock buffer = new BufferLock();
ControlCondition indexControl = new ControlCondition();
(new IndexTimeDialogThread(indexControl)).start();
(new Producer(buffer, indexControl, "抽取")).start();
(new Consumer(buffer, indexControl, "索引")).start();
}
}
// 這個class就是倉庫,是生產者跟消費者共同爭奪控制權的同步資源
class BufferLock {
public boolean IsProduceEnd;
public int BufferLength;
LinkedList<String> list = new LinkedList<String>();
BufferLock() {
BufferLength = 10;
}
//生產產品,放到緩衝區列表裡
public synchronized void push(String product) {
while (list.size() == BufferLength) {//倉庫滿
try {
wait();// 等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 倉庫不滿
notifyAll();
list.add(product);
System.out.println(" 抽取了: " + product);
System.out.println(Arrays.toString(list.toArray()));
}
//消費產品,從緩衝區列表取走
public synchronized void pop() {
while (list.size() == 0) {//倉庫空
try {
System.out.println("沒有索引資源,等待抽取");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
String product = list.removeFirst();
System.out.println(" 索引了: " + product);
System.out.println(Arrays.toString(list.toArray()));
}
}
class Producer extends Thread {
BufferLock buffer = null;
String name;
ControlCondition indexControl;
Producer(BufferLock buffer, ControlCondition indexControl, String name) {
this.buffer = buffer;
this.indexControl = indexControl;
this.name = name;
}
public void run() {
for (int i = 0; i < 200; i++) {
if (indexControl.IsInterrupt == false) { // 沒有被外部中斷
buffer.push("檔案" + i);
if (i == 199) {//抽取結束
System.out.println("抽取結束");
indexControl.IsExtractEnd = true;
}
} else {
System.out.println("抽取中斷");
break;
}
}
}
}
class Consumer extends Thread {
BufferLock buffer = null;
ControlCondition indexControl;
String name;
Consumer(BufferLock buffer, ControlCondition indexControl, String name) {
this.indexControl = indexControl;
this.buffer = buffer;
this.name = name;
}
public void run() {
while (true) {
if (indexControl.IsInterrupt == false) {// 沒有被外部中斷
if (indexControl.IsExtractEnd == true && buffer.list.size() == 0)
{// 掃描完畢而且緩衝區為空白是索引結束條件
System.out.println("索引結束");
indexControl.IsIndexEnd = true;
break;
} else
buffer.pop();
} else {
System.out.println("索引中斷");
break;
}
}
}
}
class ControlCondition {
boolean IsExtractEnd=false;
boolean IsIndexEnd=false;
boolean IsInterrupt=false;
}
/*
* 顯示索引消耗時間對話方塊線程
*/
class IndexTimeDialogThread extends Thread {
ShowDialog dlg;
ControlCondition indexControl;
public IndexTimeDialogThread(ControlCondition indexControl) {
this.indexControl = indexControl;
dlg = new ShowDialog(null, indexControl, "建立索引", false, "");
dlg.jButOK.setEnabled(false);
dlg.setVisible(true);
}
public void run() {
Date startTime = new Date();
while (true) {
Date now = new Date();
dlg.jLabelShow.setText("<html><body>正在建立索引...計時: <font color=red>"
+ (now.getTime() - startTime.getTime())
+ "</font> 毫秒</body></html>");
if (indexControl.IsIndexEnd == true) {// indexThread完成
Date endTime = new Date();
dlg.jLabelShow.setText("<html><body>索引完成!共耗時 <font color=red>"
+ (endTime.getTime() - startTime.getTime())
+ "</font> 毫秒." + "<br>請在索引菜單下查看索引日誌"
+ "</body></html>");
dlg.jButOK.setEnabled(true);
dlg.jButStopIndexThread.setEnabled(false);
break;
}
if (indexControl.IsInterrupt == true) {// indexThread中斷
Date endTime = new Date();
dlg.jLabelShow.setText("<html><body>索引被中斷!共耗時 <font color=red>"
+ (endTime.getTime() - startTime.getTime())
+ "</font> 毫秒." + "<br>請在索引菜單下查看索引日誌"
+ "</body></html>");
dlg.jButOK.setEnabled(true);
dlg.jButStopIndexThread.setEnabled(false);
break;
}
}
}
}