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