线程间通信
- 线程间通信其实就是多个线程在操作用一个资源,但是操作的动作不同。
代码示例:两个线程同时操作性别和姓名出现安全隐患
package contact;
class Res
{
String name;
String sex;
}
class Input implements Runnable
{
private Res r;
Input(Res r)
{
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+1)%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 Contact
{
public static void main(String[] args)
{
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();
}
}
//代码结果错误示例:
mike....女女女女
mike....man
丽丽....女女女女
丽丽....man
.......
错误原因:在mike 和man 输入之后输入"丽丽"时,还未输入性别,结果已经被线程2输出。
解决方式:同步,加互斥锁 synchronized
package contact;
class Res
{
String name;
String sex;
}
class Input implements Runnable
{
private Res r;
Input(Res r)
{
this.r = r;
}
public void run()
{
int x=0;
while(true)
{
synchronized (r) //加互斥锁
{
if(x==0)
{
r.name="mike";
r.sex="man";
}
else
{
r.name="丽丽";
r.sex="女女女女";
}
x=(x+1)%2;
}
}
}
}
class Output implements Runnable
{
private Res r;
Output(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized (r) //加互斥锁
{
System.out.println(r.name+"...."+r.sex);
}
}
}
}
public class Contact
{
public static void main(String[] args)
{
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();
}
}
//加入互斥锁 synchronized后运行结果:
mike....man
mike....man
.......
丽丽....女女女女
丽丽....女女女女
.......
加了互斥锁 synchronized 不能解决问题,说明互斥锁出现错误
- 检查错误:两个前提
- 一是看是否有两个线程(或多个)需要加互斥锁的地方已经加上了互斥锁
- 二是看所加的互斥锁是否一致(唯一)
互斥锁 synchronized(?)?处都可以填什么?
可以填 r、Input.class、Output.class、Contact.class
等待唤醒机制
为何输出多次?
mike....man
mike....man
.......
丽丽....女女女女
丽丽....女女女女
- 原因: 两个线程互相争夺cpu使用权,输入线程抢夺到后持续一段时间输入,等到某一时刻被输出线程抢到cpu,开始疯狂输出一段时间。
- 那么,如何实现输入一个姓名性别,输出一个相应的姓名性别呢?
这就需要使用我们的等待唤醒机制啦,这部分内容比较多而且更加重要,我们把它放到下一篇博客来讲解,嘻嘻嘻(才不是我想偷懒一天23333)
敬请期待下一篇内容吧!