Java多线程2.2.生产者与消费者之间的关系1

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cmm0401/article/details/82712000

线程间通信问题

1、线程间通信问题

(1)线程间通信问题:不同种类的线程之间针对同一个资源的操作。

(2)通过设置线程(生产者)和获取线程(消费者)针对同一个学生对象进行操作。

2、线程间通信举例

(1)创建学生类

package cn.itcast_03;
public class Student {
	String name;
	int age;
}

(2)创建生产者

package cn.itcast_03;
public class SetThread implements Runnable {
	private Student s;
	public SetThread(Student s) {
		this.s = s;
	}
	@Override
	public void run() {
		s.name = "林青霞";
		s.age = 27;
	}
}

(3)创建消费者

package cn.itcast_03;
public class GetThread implements Runnable {
	private Student s;
	public GetThread(Student s) {
		this.s = s;
	}
	@Override
	public void run() {
		System.out.println(s.name + "---" + s.age);
	}
}

(4)测试线程类:这种方式出现了问题:需要加锁解决

package cn.itcast_03;

/*
 * 分析:
 * 		资源类:Student	
 * 		设置学生数据:SetThread(生产者)
 * 		获取学生数据:GetThread(消费者)
 * 		测试类:StudentDemo
 * 
 * 问题1:按照思路写代码,发现数据每次都是:null---0
 * 原因:我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个。
 * 如何实现呢?
 * 		在外界把这个数据创建出来,通过构造方法传递给其他的类。
 * 
 */
public class StudentDemo {
	public static void main(String[] args) {
		//创建资源
		Student s = new Student();
		//设置和获取的类
		SetThread st = new SetThread(s);
		GetThread gt = new GetThread(s);
		//线程类
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(gt);
		//启动线程
		t1.start();
		t2.start();
	}
}

3、线程间通信举例的问题解决1

(1)创建学生类

package cn.itcast_03;
public class Student {
	String name;
	int age;
}

(2)创建生产者

package cn.itcast_04;
public class SetThread implements Runnable {
	private Student s;
	private int x = 0;
	public SetThread(Student s) {
		this.s = s;
	}
	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				if (x % 2 == 0) {
					s.name = "林青霞";//刚走到这里,就被别人抢到了执行权
					s.age = 27;
				} else {
					s.name = "刘意"; //刚走到这里,就被别人抢到了执行权
					s.age = 30;
				}
				x++;
			}
		}
	}
}

(3)创建消费者

package cn.itcast_04;
public class GetThread implements Runnable {
	private Student s;
	public GetThread(Student s) {
		this.s = s;
	}
	@Override
	public void run() {
		while (true) {
			synchronized (s) {
				System.out.println(s.name + "---" + s.age);
			}
		}
	}
}

(4)测试线程类

package cn.itcast_04;

public class StudentDemo {
	public static void main(String[] args) {
		//创建资源
		Student s = new Student();
		
		//设置和获取的类
		SetThread st = new SetThread(s);
		GetThread gt = new GetThread(s);

		//线程类
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(gt);

		//启动线程
		t1.start();
		t2.start();
	}
}

 * 分析:
 *         资源类:Student    
 *         设置学生数据:SetThread(生产者)
 *         获取学生数据:GetThread(消费者)
 *         测试类:StudentDemo
 *
 * 问题1:按照思路写代码,发现数据每次都是:null---0
 *              原因:我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个!
 * 如何实现呢?
 *              在外界把这个数据创建出来,通过构造方法传递给其他的类。
 * 问题2:为了数据的效果好一些,我加入了循环和判断,给出不同的值,这个时候产生了新的问题
 *             A:  同一个数据出现多次
 *             B:  姓名和年龄不匹配
 * 原因:
 *             A:  同一个数据出现多次
 *                   CPU的一点点时间片的执行权,就足够你执行很多次。
 *             B:  姓名和年龄不匹配
 *                   线程运行的随机性
 * 线程安全问题:
 *         A: 是否是多线程环境        是
 *         B: 是否有共享数据        是
 *         C: 是否有多条语句操作共享数据    是
 * 解决方案:
 *         加锁。
 *         注意:
 *             A: 不同种类的线程都要加锁。
 *             B: 不同种类的线程加的锁必须是同一把。

4、线程间通信举例的问题解决2 见下一篇博客

猜你喜欢

转载自blog.csdn.net/cmm0401/article/details/82712000
今日推荐