日期:2014-05-20  浏览次数:20806 次

大神帮我看看这个多线程的问题(2个线程轮流执行)
package Shishi;

 class Test
{

private int value;
private boolean isEmpty=true;//判断value的值是否为空的信号
public  synchronized void put( int i)
{

while(!isEmpty)
{

try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
value=i;
isEmpty=false;
notify();

}
public synchronized  int get()
{


while(isEmpty)
{
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
isEmpty=true;
notify();
return value;

}

}
class Sender extends Thread
{

private Test test;
public Sender(Test test)
{
this.test=test;

}
public void run()
{
for(int i=1;i<6;i++)
{
test.put(i);
System.out.println("Sender put:"+i);

}
}

}
class Recevier extends Thread
{
   private Test test;
   public Recevier(Test test)
   {
   
   this.test=test;
   }
public void run()
{

for(int i=1;i<6;i++)
{

System.out.println("\t\t\tReceiver get:"+test.get());
}

}
}
public class BufferLock
{

public static void main(String [] args)
{
Test test=new Test();
new Sender(test).start();
new Recevier(test).start();


}
}


我想做的是put一个然后取一个,感觉没什么错误,但是实际结果和预期结果不一致,因为结果会变动

预期结果是:
Sender put:1
Receiver get:1
Sender put:2
Receiver get:2
Sender put:3
Receiver get:3
Sender put:4
Receiver get:4
Sender put:5
Receiver get:5


随机结果1





结果2:




------解决方案--------------------
因为多线程的调度顺序是无须的,你这个只是输出的问题。test.put(i);
 System.out.println("Sender put:"+i);这两句中前面的一句执行完了后,就释放了test对象锁。然后可能进行了线程切换。
System.out.println("\t\t\tReceiver get:"+test.get());这句也是一样的道理。
------解决方案--------------------
lz,楼上说的对,你的打印语句没有放在同步块里,可能在put,和get之后发生线程切换的.我帮你改好了代码
package zz.study.multithread;

class Test {

private int value;
private boolean isEmpty = true;// 判断value的值是否为空的信号

public synchronized void put(int i) {

while (!isEmpty) {

try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
value = i;
System.out.println("Sender put:" + i);
isEmpty = false;
notify();

}

public synchronized int get() {

while (isEmpty) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("\t\t\tReceiver get:" + this.value);
isEmpty = true;
notify();
return value;

}

}

class Sender extends Thread {

private Test test;

public Sender(Test test) {
this.test = test;

}

public void run() {
for (int i = 1; i < 6; i++) {
test.put(i);
}
}

}

class Recevier extends Thread {
private Test test;

public Recevier(Test test) {

this.test = test;
}

public void run() {

for (int i = 1; i < 6; i++) {
test.get();
}

}
}

public class BufferLock {

public static void main(String[] args) {
Test test = new Test();
new Sender(test).start();
new Recevier(test).start();