/*
* 生产者和消费者
*/
package com.liu.thread;public class TestDemo15 { public static void main(String[] args) {
Queue queue=new Queue();
Producer p=new Producer(queue);
Consumer c=new Consumer(queue);
new Thread(p).start();
new Thread(c).start();
}}class Producer implements Runnable{
private Queue queue;
public Producer(Queue queue)
{
this.queue=queue;
}
public void run(){
for(int i=0;i<10;i++)
{
System.out.println("Producer put:"+i);
queue.put(i);
}
}
}class Consumer implements Runnable{
private Queue queue;
public Consumer(Queue queue){
this.queue=queue;
}
public void run(){
while(true)
{
System.out.println("Consumer get:"+queue.get());
}
}
}class Queue{ private int value; private boolean isFull=false;
public synchronized void put(int value)
{
if(!isFull)
{
this.value=value;
isFull=true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello");
}
public synchronized int get()
{
if(!isFull)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFull=false;
notify();
return value;
}
}
肖申克的救赎(372175908) 21:29:36
Producer put:0
Consumer get:0
hello
Producer put:1
Consumer get:1
hello
Producer put:2
hello
Producer put:3
Consumer get:2
Consumer get:3
hello
Producer put:4
Consumer get:4
hello
Producer put:5
Consumer get:5
hello
Producer put:6
Consumer get:6
hello
Producer put:7
Consumer get:7
hello
Producer put:8
Consumer get:8
hello
Producer put:9
Consumer get:9
hello谁能帮我解释下这个运行结果?为什么出现了连续put()的情况?wait()方法不是要等notify()调用后才会恢复吗?
* 生产者和消费者
*/
package com.liu.thread;public class TestDemo15 { public static void main(String[] args) {
Queue queue=new Queue();
Producer p=new Producer(queue);
Consumer c=new Consumer(queue);
new Thread(p).start();
new Thread(c).start();
}}class Producer implements Runnable{
private Queue queue;
public Producer(Queue queue)
{
this.queue=queue;
}
public void run(){
for(int i=0;i<10;i++)
{
System.out.println("Producer put:"+i);
queue.put(i);
}
}
}class Consumer implements Runnable{
private Queue queue;
public Consumer(Queue queue){
this.queue=queue;
}
public void run(){
while(true)
{
System.out.println("Consumer get:"+queue.get());
}
}
}class Queue{ private int value; private boolean isFull=false;
public synchronized void put(int value)
{
if(!isFull)
{
this.value=value;
isFull=true;
notify();
}
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hello");
}
public synchronized int get()
{
if(!isFull)
{
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFull=false;
notify();
return value;
}
}
肖申克的救赎(372175908) 21:29:36
Producer put:0
Consumer get:0
hello
Producer put:1
Consumer get:1
hello
Producer put:2
hello
Producer put:3
Consumer get:2
Consumer get:3
hello
Producer put:4
Consumer get:4
hello
Producer put:5
Consumer get:5
hello
Producer put:6
Consumer get:6
hello
Producer put:7
Consumer get:7
hello
Producer put:8
Consumer get:8
hello
Producer put:9
Consumer get:9
hello谁能帮我解释下这个运行结果?为什么出现了连续put()的情况?wait()方法不是要等notify()调用后才会恢复吗?
这个问题是Java规范里面明确说明的:第一,Java编译器是有所谓的优化编译执行的,语句并不一定绝对按照你书写的顺序来执行,所以,两个线程并不一定按照你的程序中书写的顺序严格交替执行。第二,Java虚拟机上多线程之间的执行顺序是一个线程调度问题,Java虚拟机有自己的调度算法,并不是按照简单的先来先执行的原则,而且,还可能在不同的时候运行同一个程序,其线程执行顺序也不一样。
hello
Consumer get:0
Producer put:1
hello
Consumer get:1
Producer put:2
hello
Consumer get:2
Producer put:3
hello
Consumer get:3
Producer put:4
hello
Consumer get:4
Producer put:5
hello
Consumer get:5
Producer put:6
hello
Consumer get:6
Producer put:7
hello
Consumer get:7
Producer put:8
hello
Consumer get:8
Producer put:9
Consumer get:9
hello
package CSDN;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class BlockingQueueTest { public static void main(String[] args) {
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1);
AProducer p = new AProducer(queue);
AConsumer c = new AConsumer(queue); Thread pThread = new Thread(p, "Producer");
Thread cThread = new Thread(c, "Producer"); pThread.start();
cThread.start();
}
}class AProducer implements Runnable { private BlockingQueue<Integer> q; public AProducer(BlockingQueue<Integer> queue) {
q = queue;
} @Override
public void run() {
for (int i = 0; i <= 10; i++) {
try {
q.put(i);
System.out.println("Producer put " + i);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}class AConsumer implements Runnable { private BlockingQueue<Integer> q; public AConsumer(BlockingQueue<Integer> queue) {
q = queue;
} @Override
public void run() {
while (true) {
try {
int i = q.take();
System.out.println("Consumer get " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}}
运行后然后看看结果
Producer put 0
Producer put 1
Consumer get 0
Producer put 2
Consumer get 1
Producer put 3
Consumer get 2
Producer put 4
Consumer get 3
Producer put 5
Consumer get 4
Producer put 6
Consumer get 5
Producer put 7
Consumer get 6
Producer put 8
Consumer get 7
Producer put 9
Consumer get 8
Producer put 10
Consumer get 9
Consumer get 10结果还是不对,但是根据数字来看,应该程序跑起来是完全没有错误的,完全按照设想的走的。所以现在看来不能光按照println的显示来判断程序的运行顺序啊。
1.多个生产者之间共用同一个锁。多个消费者之间共用同一个锁,生产者和消费者之间不能共用这个"排队"的锁。
2.不管生产者还是消费者来访问仓库都要上锁。Queue {
private 仓库;
private 生产排队;
private 消费排队; 产品 get() {
synchronize(消费排队){
synchronize(仓库锁){
if(仓库空了){
仓库.wait(); //当仓库空了时,排队消费者队列中第一个消费者在等,它后面的消费者当然也在等,因为第一个人占用了消费者队列的锁。
}
产品 = 仓库.getFirst();
仓库.notifyAll(); //告诉生产者仓库里有空位了。
return 产品;
}
}
} void put(产品){
synchronize(生产者排队){
synchronize(仓库锁){
if (仓库满了){
仓库.wait(); //仓库满了,第一个生产者在再,其它生产也在等,因为第一个人占用生产者排队的锁。
} 仓库.putLast(); 仓库.notifyAll(); //告诉消费者仓库里有东西了。
}
} }}
http://blog.csdn.net/KingWolfOfSky/archive/2010/04/08/5464990.aspx