代码如下:
目的是要打出“张三”“男”,“李四”“女”。但是我只能打印出“张三”的信息,却无法打印出“李四”的信息,请问这是怎么回事?谢谢
class Producer implements Runnable
{
Q q;
public Producer(Q q)
{
this.q = q;
}
public void run()
{
int i=0;
while(true)
{
synchronized(q)
{
if(i==0)
{
q.name="zhangsan";
try{Thread.sleep(1);}catch(Exception e){}
q.sex="male";
System.out.println(i);
}
else
{
q.name="lisi";
q.sex="female";
}
}
i=(i+1)%2;
}
}
}
class Consumer implements Runnable
{
Q q;
public Consumer(Q q)
{
this.q = q;
}
public void run()
{
while(true)
{
synchronized(q)
{
System.out.print(q.name);
System.out.println(":" + q.sex);
}
}
}
}
class Q
{
String name="unknown";
String sex="unknown";
}
class ThreadCommunication
{
public static void main(String[] args)
{
Q q = new Q();
new Thread(new Producer(q)).start();
new Thread(new Consumer(q)).start();
}
}
对不起,你真的应该用[code]来框下,我没有看到你的[b]}[/b]
synchronized(q),2个线程很公平的获得q这个对象的monitor,也就是获得锁
[code="java"]
while(true)
{
synchronized(q)
{
System.out.print(q.name);
System.out.println(":" + q.sex);
}
}
[/code]
另外一个是
[code="java"]
while(true)
{
synchronized(q)
{
if(i==0)
{
q.name="zhangsan";
try{Thread.sleep(1);}catch(Exception e){}
q.sex="male";
System.out.println(i);
}
else
{
q.name="lisi";
q.sex="female";
}
}
i=(i+1)%2;
}
[/code]
所以有可能,Producer一直在生产,而Consumer因为没有获得q对象的monitor,从而没有打印出
[code="java"]
System.out.print(q.name);
System.out.println(":" + q.sex);
[/code]
你在
i=(i+1)%2; 下面加一个 q.wait(); 表示拥有q对象monitor的当前线程等待
在
System.out.print(q.name);
System.out.println(":" + q.sex);
下面 q.notify(); 表示唤醒一个q对象等待的线程
i=(i+1)%2;
i =0 那么不就永远是0了
实验了一下你的程序,是可以输出lishi的,只不过张三和李四的输出不是相隔输出的。
[code="java"]
if(i==0)
{
q.name="zhangsan";
try{Thread.sleep(1);}catch(Exception e){}
q.sex="male";
System.out.println(i);
}
else
{
q.name="lisi";
q.sex="female";System.out.println(i);
}
i=(i+1)%2;
[/code]
如果else里的输出的话,就可以看到0和1是间隔输出的。
但是 zhangsan 和 lishi的输出不是相隔的,主要是因为Consumer这个线程输出的时候节奏赶的正好有些不一样!
给个例子,不知道这样能不能满足你的需求,消费总会在生产之后执行,但不是生产A,紧接着就消费A:
[code="java"]
/*
*来源: http://eric-619.iteye.com/blog/693681
public class ProCon{ //主方法
public static void main(String[] args){
SyncStack stack = new SyncStack();
Consumer p = new Consumer(stack);
Producer c = new Producer(stack);
new Thread(p).start();
new Thread(c).start();
}
}
class Producer implements Runnable{ //生产者
private SyncStack stack;
public Producer(SyncStack stack){
this.stack = stack;
}
public void run(){
for (int i = 0; i < stack.pro().length; i++){
String product = "产品"+i;
stack.push(product);
System.out.println("生产了: "+product);
try{
Thread.sleep(200);
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{ //消费者
private SyncStack stack;
public Consumer(SyncStack stack) {
this.stack = stack;
}
public void run(){
for(int i = 0; i < stack.pro().length; i++){
String product = stack.pop();
System.out.println("消费了: "+product);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class SyncStack{ // 此类是(本质上:共同访问的)共享数据区域
private String[] str = new String[10];
private int index;
public synchronized void push(String sst){ //供生产者调用
if(index == sst.length()){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.notify(); //唤醒在此对象监视器上等待的单个线程
str[index] = sst;
index++;
}
public synchronized String pop(){ //供消费者调用
if(index == 0){
try{
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
notify();
index--;
String product = str[index];
return product;
}
public String[] pro(){ //就是定义一个返回值为数组的方法,返回的是一个String[]引用
return str; //这是一个String[]引用
}
}
[/code]