多线程中的锁机制

1、为什么要加入锁机制?

  首先看一下单例设计模式中懒汉式(详情请点击博客《设计模式之--单例模式》)的一段代码:

<span style="font-size:14px;">public class Student {  
    private Student() {  
    }  
    //声明对象的引用,但是不创建对象  
    private static Student s = null;  
    //调用公共方法时才创建对象  
    public static Student getStudent() {  
        // 如果t是null的时候,创建对象  
        if (s == null) {  
            s = new Student();  
        }  
        //否则,返回s  
        return s;  
    }  
}</span>
  这段代码如果放在多线程中是不安全的,为什么呢?

  假设这个程序中有两条线程1和2,那么当两条线程都执行到了if (s == null)这一步,此时1号线程抢到了CPU的执行权,1号线程就通过了if(s==null)的验证,但是当1号刚要执行s = new Student()之前,2号线程又抢到了CPU执行权,因为这时候1号还没有创建对象,所以2号线程也能通过if(s==null)的验证,来到s = new Student()这一步。之后1和2就会各自创建一个对象,那么,这个单例模式就算是创建失败了。这叫做线程安全问题。

2、线程安全问题如何产生的呢?

  是线程的随机性和延迟性,线程可以随便抢夺CPU资源,谁也不知道下一刻是谁抢到资源,这导致了线程访问共享数据出现了问题。

3、如何解决线程安全问题,就要用到多线程的锁机制。

  锁机制是将可能出问题的代码用锁对象锁起来,一般不会是所有的代码都有问题,所以,我们只需要找到那些可能出问题的代码锁起来,将锁起来来的代码看做一个整体,只有这个整体完毕,别人才能继续访问,这个被锁起来的整体就叫做同步代码块。这样,使得同一时间只能有一个线程来访问这一个同步代码块,当线程进入同步代码块时就会向外界传递一个消息:这块代码已经被锁了,等我出来之后你再进去。这类似于数据库中的“事务”概念。这样,就保证了每次只有一条线程执行代码块中的内容。

  锁的格式:

<span style="font-size:14px;">  			synchronized(锁对象)
  			{
  				需要被锁的代码;
  			}</span>
  以上面单例模式代码为例加锁:

<span style="font-size:14px;">public class Student {  
    private Student() {  
    }  
    private static Student s = null;  
    //在方法之上加锁  
    public synchronized static Student getStudent() {  
        if (s == null) {  
            s = new Student();  
        }  
        return s;  
    }  
}  </span>

小结:怎么确定是否应该被锁,如何判断是否有线程安全问题?

  (1)看有没有共享数据(这里的共享数据是s)。

  (2)看对共享数据的操作是不是多条语句(if 判断和s的赋值)。

  (3)看是不是在多线程程序中。

  如果代码满足这三个条件,那么就说明应该加锁了。


评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值