线程安全——关于锁对象的理解

锁对象是什么:

在初次接触到线程锁对象这个问题时,我并没有在意锁对象这个问题,只知道被Synchroized修饰的代码块只能同时被一个线程访问。这样理解虽然简单,却也很片面,只是设想到了一个线程占用一个锁的情况,却没有考虑到一个线程其实可以拥有多把锁,并且占用它。


什么是锁对象?

锁对象其实就是锁,锁对象可以是当前Runnable实现类的对象,也可以是Runnable实现类的类,即.class。
1、synchronized修饰方法时 锁对象时当前的Runnable实现类的对象
2、synchronized修饰静态方法 锁对象是Runnable实现类的类,即.class

class MyThread implements Runnable {}//自定义了Runnable实现类
 public synchronized void setStr() {} //synchronized修饰方法时 锁对象时当前的Runnable实现类的对象
  public synchronized static void uppSet3(){}//synchronized修饰静态方法 锁对象是Runnable实现类的类,即.class
       //在需要使用到该类对象的类里面,创建锁对象
        MyThread run1 =new MyThread();

此时我们创建线程时,如果传入相同的锁对象,那么对于被synchronized修饰的方法或者代码块就被同一把锁对象run1给锁住了,这样就能实现线程安全!

//创建线程对象
        Thread t1 =new Thread(run1,"t1");
        Thread t2 =new Thread(run1,"t2");

锁对象一定要是实现Runnable实现类的对象吗

锁对象也不一定要是实现Runnable实现类的对象,我们可以随便定义一个类,为其创建对象,并将该对象作为锁对象,尽管这个类实际上并没有任何的业务逻辑上的实现。

 public static Object lock =new Object();//随便定义了一个对象
 ‘’‘’在需要的代码块中将其作为锁对象‘’‘’‘’
  @Override
        public void run() {
            //声明同步代码块,其中 的代码同时只能被一个线程访问
          synchronized (Acount2.lock){
              if (Acount2.balance>monry){
                  try{
                      TimeUnit.SECONDS.sleep(1);
                  }catch (InterruptedException E){
                      System.out.println(E.getMessage());
                  }
                  //更改余额
                  Acount2.balance = Acount2.balance-monry;
                  System.out.println(name+"取钱成功,当前余额"+Acount2.balance);
              }
              else {
                  System.out.println(name+"取钱失败,当前余额"+Acount2.balance);
              }
          }
        }

总结

每个线程可以拥有多个锁对象(锁),当线程要访问被锁管理的代码块时,都先要获得这把锁的使用权(看看当前这把锁是否被其他线程所占用)。如果该线程所需要的锁被其他线程正占用着,该线程只能等待,等到其他线程释放之后才能使用,如果其他线程不释放,而这个线程又一直等着要用,那么就会造成死锁问题,关于死锁问题,将在下一篇的"线程死锁问题案例分析及解决方案"中详细描述。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值