您的位置:首页 > 编程语言 > Java开发

Java---17---多线程之间的通信

2015-01-18 20:13 141 查看
在前面我们已经介绍了多线程编程中使用同步机制的重要性,并学会了如何实现同步的方法来正确的访问共享资源。这些线程之间的关系是平等的,批次之间并不存在依赖,他们各自竞争CPU的资源,互不相让,并且还无条件的阻止其他线程对共享资源的访问。然而,也有很多现实问题要求不仅仅要同步的访问同一共享资源,而且线程间还彼此牵制,通过相互通信来向前推进。那么,多个线程之间是如何进行通信的呢?

线程间的通信其实就是多个线程在操作同一个资源,但操作的动作不同。

class Res {
	String name;
	String sex;
}

class Input implements Runnable {
	private Res r;

	public Input(Res r) {
		// TODO Auto-generated constructor stub
		this.r = r;
	}

	public void run() {
		int x = 0;
		while (true) {
			if (x == 0) {
				r.name = "mike";
				r.sex = "man";
			} else {
				r.name = "丽丽";
				r.sex = "女女女";
			}
			x = ++x % 2;
		}
	}
}

class Output implements Runnable {
	private Res r;

	Output(Res r) {
		this.r = r;
	}

	public void run() {
		while (true) {
			System.out.println(r.name + "----" + r.sex);
		}
	}
}

public class Communicate {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Res r = new Res();
		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();
	}
}


但是这样写的会出现名字与性别不相匹配的情况。

这就表明了出现了安全问题,当出现安全问题时就要想到需要同步。

那我们加上同步再试一试:

class Res {
	String name;
	String sex;
}

class Input implements Runnable {
	private Res r;
	Object obj = new Object();

	public Input(Res r) {
		// TODO Auto-generated constructor stub
		this.r = r;
	}

	public void run() {
		int x = 0;
		while (true) {
			synchronized (obj) {
				if (x == 0) {
					r.name = "mike";
					r.sex = "man";
				} else {
					r.name = "丽丽";
					r.sex = "女女女";
				}
				x = ++x % 2;
			}
		}
	}
}

class Output implements Runnable {
	private Res r;
	Object obj = new Object();
	Output(Res r) {
		this.r = r;
	}

	public void run() {
		while (true) {
			synchronized (obj)
			{
				System.out.println(r.name + "----" + r.sex);
			}
		}
	}
}

public class Communicate {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Res r = new Res();
		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();

	}
}


但是这样做之后还是没有解决出现的问题。

那么还是要考虑那两个原则:

1.是否是两个及两个以上的线程?(满足)

2.是否是同一个锁?(??)



this 是本类对象就更不用想了。

在内存中已经有了四个.class的对象,用哪一个都是可以的。

class Res {
	String name;
	String sex;
}

class Input implements Runnable {
	private Res r;

	public Input(Res r) {
		// TODO Auto-generated constructor stub
		this.r = r;
	}

	public void run() {
		int x = 0;
		while (true) {
			synchronized (Input.class) {
				if (x == 0) {
					r.name = "mike";
					r.sex = "man";
				} else {
					r.name = "丽丽";
					r.sex = "女女女";
				}
				x = ++x % 2;
			}
		}
	}
}

class Output implements Runnable {
	private Res r;
	Object obj = new Object();

	Output(Res r) {
		this.r = r;
	}

	public void run() {
		while (true) {
			synchronized (Input.class) {
				System.out.println(r.name + "----" + r.sex);
			}
		}
	}
}

public class Communicate {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Res r = new Res();
		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();

	}
}


但是在本例中,资源r也是独一无二的,也就是说,如果将锁换成是r的话也可以。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: