原因是这样的,
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
其实是开了两个线程,虽然你在buffer的底层方法加了锁,但是JVM执行线程的顺序是不可期待的,你可以通过设置线程的权值宏观地控制或者调用相关的方法,正如你执行的结果,其实只是其中一种结果,如果你多测试几次,结果应该是不同的,而且你每次put进去的数字是随即的,有这样的结果就很正常了。
new Thread(new Producer(buffer)).start();
new Thread(new Consumer(buffer)).start();
其实是开了两个线程,虽然你在buffer的底层方法加了锁,但是JVM执行线程的顺序是不可期待的,你可以通过设置线程的权值宏观地控制或者调用相关的方法,正如你执行的结果,其实只是其中一种结果,如果你多测试几次,结果应该是不同的,而且你每次put进去的数字是随即的,有这样的结果就很正常了。
不过,哪一个线程先SRART哪一个线程先抢点资源,然后直到更高级的线程抢点资源
一般来说,你设置线程的优先级可以预计线程的执行,但也有些特别的,比如WINDOWS系统中,界面线程就较为优先
public class ConProd {
public static void main(String args[]) {
Buffer buffer=new Buffer();
new Thread(new Consumer(buffer)).start();
new Thread(new Producer(buffer)).start();
}
}//临界资源
class Buffer{
int data;
boolean dataready=false;
Object lockProducer=new Object();
public synchronized int get(){
System.out.println("into gets");
if (dataready==false){
try{
wait();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
dataready=false;
System.out.println("get "+data);
notifyAll();
System.out.println("out get");
return data;
}
public synchronized void put(int i){
System.out.println("into put");
if(dataready==true){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
data=i;
dataready=true;
System.out.println("put "+data);
System.out.println("out put");
notifyAll();
}
}//生产者
class Producer implements Runnable{
Buffer buffer;
public Producer (Buffer buffer){
this.buffer=buffer;
}
public void run(){
int i;
while(true){
System.out.println("run Producer");
try{
Thread.sleep((int)Math.random()*1000);
}catch(InterruptedException e){
e.printStackTrace();
}
i=(int)(Math.random()*100);
buffer.put(i);
//System.out.println(i+" produced.");
}
}
}//消费者
class Consumer implements Runnable{
Buffer buffer;
public Consumer (Buffer buffer){
this.buffer=buffer;
}
public void run(){
while(true){
System.out.println("run Consumer");
try{
Thread.sleep((int)Math.random()*1000);
}
catch(InterruptedException e){
e.printStackTrace();
}
buffer.get();
}
}
}
run Consumer
into gets
run Producer
into put
put 35
out put
get 35
out get
run Consumer
run Producer
into gets
into put
put 30
out put
get 30
out get
run Consumer
run Producer
into gets
into put
put 77
out put
get 77
out get
run Consumer
run Producer
into gets
into put
put 96
out put
get 96
出现这种情况:
当Consumer线程得到一个数退出get方法时(这是释放了线程锁),本来像立即输出得到地数据,哪知道,cpu被producer抢了,所以将执行set方法,所以有跟着输出了set地语句而没有输出get方法信息了
昨天是在winXP上测试的。刚才在win2000下测试一切正常。看来和操作系统也有关系。to eddygtimegod(dark), azqf121(阿晚):
如eddygtimegod所说,确实开了两个线程,但是product线程只开了一个。
按照我的理解,put()方法既然已经加锁,那么在它执行完以前,dataready变量值任然是false;第二个试图进入的生产者对象应该被驻塞,那么它怎么会有机会再次调用System.out.println(i+" produced.")语句呢?
^^while
//:-)