有一道这样的题目,用多线程方式实现生产者消费者模式,生产者随便产生一个0-1000之间的数,消费者打印出生产的数据。当随机产生的数是0时,生产线程和消费线程都退出。
思路:用一个队列Queue存储产生的数据,队列作为共享数据在生产者和消费者共享。
生产者:
/**
*数据生产者
*/
import java.util.Queue;
import java.util.Random;
/**
* 名称:类的中文名称 <br>
* 功能:对类的功能进行说明 <br/>
* <br/>
*
* @since JDK 1.7
* @see
* @author rdf
*/
public class ProducerNum implements Runnable {
private Queue q;
public ProducerNum(Queue q) {
this.q = q;
}
@Override
public void run() {
Random random = new Random();
int count = 0;
while (true) {
int i = random.nextInt(10);
if (i != 0) {
count++;
q.add(i);
System.out.println(i);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
q.add(i);
System.out.println("这是第" + count + "次" + ":" + i);
break;
}
}
}
}
消费者:
/**
*消费数据
*/
package pcmodl;
import java.util.Queue;
/**
* 名称:类的中文名称 <br>
* 功能:对类的功能进行说明 <br/>
* <br/>
*
* @since JDK 1.7
* @see
* @author rdf
*/
public class ConsumerNom implements Runnable {
private Queue q;
/**
* 构造方法: ConsumerNom.
*
*/
public ConsumerNom(Queue q) {
this.q = q;
}
@Override
public void run() {
while (true) {
if (!q.isEmpty()) {
if ((int) q.peek() == 0) {
System.out.println(q.peek());
break;
}
System.out.println(q.poll());
System.out.println("************");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
}
}
}
}
主线程:
/**
*主线程
*/
package pcmodl;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 名称:类的中文名称 <br>
* 功能:对类的功能进行说明 <br/>
* <br/>
*
* @since JDK 1.7
* @see
* @author rdf
*/
public class ProduceConsumer {
/**
* <b>名称</b>:方法的中文名称 <br/>
* <br/>
* <b>说明</b>:说明方法的功能和使用要点 <br/>
* <br/>
*
* @param args
*
* @see
*/
public static void main(String[] args) {
Queue q = new LinkedList<>();
ExecutorService service = Executors.newCachedThreadPool();//使用newCachedThreadPool线程池
ProducerNum p = new ProducerNum(q);
ConsumerNom c = new ConsumerNom(q);
// Thread t1 = new Thread(p);
// Thread t2 = new Thread(c);
// t1.start();
// t2.start();
service.submit(p);
service.submit(c);
}
}
总结:程序在执行时,消费者线程老是无故结束,不在执行,由于本人对多线程学习不够深,不明白为什么出现这种情况。个人猜测是应为数据共享是线程阻塞造成的。
public class ConsumerNom implements Runnable {
private Queue q;
/**
* 构造方法: ConsumerNom.
*
*/
public ConsumerNom(Queue q) {
this.q = q;
}
@Override
public void run() {
while (true) {
if (!q.isEmpty()) {
if ((int) q.peek() == 0) {
System.out.println(q.peek());
break;
}
System.out.println(q.poll());
System.out.println("************");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else {//消费者增加这样一段代码,进过测试,没有出现上述问题。
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程类也可以集成Thread类:
生产者:
public class ProducerNum extends Thread {
private Queue q;
public ProducerNum(Queue q) {
this.q = q;
}
@Override
public void run() {
Random random = new Random();
int count = 0;
while (true) {
int i = random.nextInt(10);
if (i != 0) {
count++;
q.add(i);
System.out.println(i);
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
q.add(i);
System.out.println("这是第" + count + "次" + ":" + i);
break;
}
}
}
}
消费者:
public class ConsumerNom extends Thread {
private Queue q;
/**
* 构造方法: ConsumerNom.
*
*/
public ConsumerNom(Queue q) {
this.q = q;
}
@Override
public void run() {
while (true) {
if (!q.isEmpty()) {
if ((int) q.peek() == 0) {
System.out.println(q.peek());
break;
}
System.out.println(q.poll());
System.out.println("************");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else {
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}