问答详情
源自:5-1 总结及展望

关于使用Thread.yield()进行线程通讯的问题

//代码1
package communication;

import java.util.Random;

public class Flag {
	public static void main(String[] args) {
		FlagSender f = new FlagSender();
		FlagRec r = new FlagRec(f);
		Thread t1 = new Thread(f);
		Thread t2 = new Thread(r);
		t1.start();
		t2.start();
	}
}
class FlagSender implements Runnable{
	private int theValue;
	private boolean flag;
	
	public int getTheValue() {
		return theValue;
	}

	public void setTheValue(int theValue) {
		this.theValue = theValue;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			while(flag){
				Thread.yield();
			}
			theValue = new Random().nextInt(1000);
			System.out.println("send the value is "+theValue);
			flag = true;
		}
	}
}
class FlagRec implements Runnable{
	private FlagSender f; 
	public FlagRec(FlagSender f) {
		super();
		this.f = f;
	}

	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			while(!f.isFlag()){
				Thread.yield();
			}
			System.out.println("receive the value is "+f.getTheValue());
			f.setFlag(false);
		}
	}
}
//代码2
package communication;

import java.util.Random;

public class WrongOfFlag {
	public static void main(String[] args) {
		FlagSender1 f = new FlagSender1();
		FlagRec1 r = new FlagRec1();
		Thread t1 = new Thread(f);
		Thread t2 = new Thread(r);
		t1.start();
		t2.start();
	}
}
class FlagSender1 implements Runnable{
	private int theValue;
	private boolean flag;
	
	public int getTheValue() {
		return theValue;
	}

	public void setTheValue(int theValue) {
		this.theValue = theValue;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			while(flag){
				Thread.yield();
			}
			theValue = new Random().nextInt(1000);
			System.out.println("send the value is "+theValue);
			flag = true;
		}
	}
}
class FlagRec1 implements Runnable{
	FlagSender f = new FlagSender();
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			while(!f.isFlag()){
				Thread.yield();
			}
			System.out.println("receive the value is "+f.getTheValue());
			f.setFlag(false);
		}
	}
}

为什么要让FlagSender作为FlagRec的成员,像代码二中直接new了FlagSender为什么结果只输出一个send the value is 138,然后就死循环空程序了,结果如下图http://img.mukewang.com/5895dbb30001498806280141.jpg

提问者:_Everglow 2017-02-04 21:49

个回答

  • 福山润
    2017-02-06 22:18:04
    已采纳

    代码1:两个线程同时走,他俩公用一个FlagSender对象里面的flag,当线程t1走第一遍时,flag等于false,不等待直接输出,然后将falg致成true,线程t1等待,这时候线程t2 while里面的!f.isFlag() 为false,所以往下进行输出又将flag致成false,这时线程t1又开始执行。以此类推。

    代码2:两个对象都在while里面进行死循环,所以只打印一次。