线程通信的安全问题,如何加锁?
1.线程通信就是多个线程对同一个资源进行不同的处理。
( 比如,现在要对学生档案输入输出,学生属于资源,然而给学生名字,性别初始化就是一个线程,(输入线程)
然后对数据进行输出,此时输出也是一个线程(输出线程))
2.线程通信中会出现什么安全问题?
(0线程) A-----------------------------------------------------学生--------------------------------------------------------B(1线程)
输入(张三,男) 输出()
输入(小花,女) 输出()
public void run()
{ int x=0; class Resource // 创建一个资源类 System.out.println(r.name+r.sex)
{
String name;
String sex;
}
while(x>=0)
{
{ if (x==0)
{r. name="张三";
r.sex="男";
}
else {
r. name="小花";
r.sex="女";
}}
x=((x+1)%2}
}
}
上述代码中 有可能线程0,输入了“张三,男”后,然后cpu并没有切换执行权到线程0,就是输出线程。这时候如果线程0接着用执行权,然后当输入了小花的时候,还没来得
及输入性别,被切换了cpu执行权,这时候就会输出了 “小花 男”,这个就是线程通信的安全问题。
3.线程通信如何加锁?
a.线程的安全性问题可以使用 同步函数或者同步代码块进行加锁。同步代码块必须附上一个对象,然而同步函数默认是this。如果对上述代码进行加锁,选择用同步代码块加锁。
public void run()
{ int x=0;
while(x>=0) 思路:如果将张三,男。 小花,女 进行封装。为什么这样还是有安全性问题呢?
明确一点:单单封装了0线程,安全性问题还是存在的,
误区:认为将if语句锁起来,他们就一定配套出现,张三就是男的,小花就是女的。因为已经加了锁。
{
synchronized(obj){
{ if (x==0)
{r. name="张三";
r.sex="男";
} 然而同步代码块的使用必须有线程,只有0线程,就是一个线程,同步代码块明显没作用。
else {
因为线程通信和之前遇到的多线程有一丢丢不一样 。
r. name="小花"; 普通多线程,他们公用一个代码块,而线程通信使用的是不同代码块执行。
r.sex="女";
}}}
x=((x+1)%2);
}
}
4. 线程通信中 选择什么对象引用对同步代码块最好呢?
{ 加入创造了一个object的对象, 不用线程创建不同的对象,明显无法加锁。
然而资源,就是不同线程处理同一资源,同对象,固选择他们的共有使用对象最好。
}
5.完整实例代码
class Resource
{
String name;
String sex;
}
class Input implements Runnable
{ Object q=new Object();
private Resource r;
Input( Resource r)
{this.r=r;
}
public void run()
{ int x=0;
while(x>=0)
{
synchronized(r){
{ if (x==0)
{r. name="张三";
r.sex="sex";
}
else {
r. name="李四";
r.sex="男";
}}}
x=((x+1)%2);
}
}
}
class Output implements Runnable
{
Resource r ;
Output( Resource r){
this.r=r;}
public void run()
{ while (true)
{synchronized (r){
System.out.println(r.name+"哈哈哈"+r.sex);
}}
}
}
class Zhu
{
public static void main(String []args)
{Resource r=new Resource();
Input in=new Input(r);
Output out=new Output(r);
Thread t1=new Thread(in);
Thread t2=new Thread(out);
t1.start();
t2.start();
}
}
javase线程间通信(锁)的应用
最新推荐文章于 2023-04-06 21:47:19 发布
