javase线程间通信(锁)的应用

本文探讨了线程通信中的安全问题,通过示例说明了未正确加锁可能导致的数据不一致,并介绍了如何使用同步代码块解决此类问题。

 线程通信的安全问题,如何加锁?
   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();
 
}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值