生产者,消费者,固定长度缓冲区,此外外部可以中断线程
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;
}
}
}
}