线程间通信问题
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: 不同种类的线程加的锁必须是同一把。