读书人

大神帮小弟我看看这个多线程的有关问题

发布时间: 2013-10-11 14:52:39 作者: rapoo

大神帮我看看这个多线程的问题(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个线程轮流执行)

结果2:
大神帮小弟我看看这个多线程的有关问题(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();



}
}
[解决办法]
线程的执行本来就是随机顺序的,要是轮流执行的话,这里面就有明确的顺序了。所以只能把存一个取一个的操作放到一个同步方法中。或者干脆不适用线程,自己设置这种轮流操作过程。

读书人网 >J2SE开发

热点推荐