动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

浅谈对象锁

05-26 15:28 1194浏览
举报 T字号
  • 大字
  • 中字
  • 小字

对象锁是指Java为临界区synchronized(Object)语句指定的对象进行加锁,对象锁是独占排他锁。对象锁用于程序片段或者method上,此时将获得对象的锁,所有想要进入该对象的synchronized的方法或者代码段的线程都必须获取对象的锁,如果没有,则必须等其他线程释放该锁。

对于对象锁来说,又可以分为两个,一个是方法锁,一个是同步代码块锁,我们重点要讲的就是同步代码块锁。

同步代码块锁主要是对代码块进行加锁,举个例子:

public class SynTest01 implements Runnable {
    Object object = new Object();
    public static void main(String[] args) throws InterruptedException {
        SynTest01 syn = new SynTest01();
        Thread thread1 = new Thread(syn);
        Thread thread2 = new Thread(syn);
        thread1.start();
        thread2.start();
        //线程1和线程2只要有一个还存活就一直执行
        while (thread1.isAlive() || thread2.isAlive()) {}
        System.out.println("main程序运行结束");
    }
    @Override
    public void run() {
        synchronized (object) {
            try {
                System.out.println(Thread.currentThread().getName() 
                        + "线程执行了run方法");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() 
                        + "执行2秒钟之后完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在这个例子中,我们使用了synchronized锁住了run方法中的代码块。表示同一时刻只有一个线程能够进入代码块。就好比是去医院挂号,前面一个人办完了业务,下一个人才开始。

在这里面我们看到,线程1和线程2使用的是同一个锁,也就是我们new的Object。如果我们让线程1和线程2每一个人拥有一个锁对象呢?

public class SynTest01 implements Runnable {
    Object object1 = new Object();
    Object object2 = new Object();
    public static void main(String[] args) throws InterruptedException {
        SynTest01 syn = new SynTest01();
        Thread thread1 = new Thread(syn);
        Thread thread2 = new Thread(syn);
        thread1.start();
        thread2.start();
        //线程1和线程2只要有一个还存活就一直执行
        while (thread1.isAlive() || thread2.isAlive()) {}
        System.out.println("main程序运行结束");
    }
​
    @Override
    public void run() {
        synchronized (object1) {
            try {
                System.out.println(Thread.currentThread().getName() 
                        + "线程执行了object1");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() 
                        + "执行object1完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        synchronized (object2) {
            try {
                System.out.println(Thread.currentThread().getName() 
                        + "线程执行object2");
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName() 
                        + "执行object2完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

现在线程1和线程2每个人拥有一把锁,去访问不同的方法资源。这时候会出现什么情况呢?也就是说,相当于两个业务有俩窗口都可以办理,但是两个任务都需要排队办理。

同步代码块锁主要是对代码块进行加锁,此时同一时刻只能有一个线程获取到该资源,要注意每一把锁只负责当前的代码块,其他的代码块不管。当然,我们介绍的只是最简单的对象锁的使用,想要考验自己的小伙伴可以加大难度,去动力节点在线的视频课程找到更加复杂的实例来论证。

0人推荐
共同学习,写下你的评论
0条评论
代码小兵498
程序员代码小兵498

153篇文章贡献528999字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

提枪策马乘胜追击04-21 20:01

Spring常见面试题

代码小兵92504-17 16:07

Java零基础实战项目——五子棋

代码小兵98804-25 13:57

Java string类详解

杨晶珍05-11 14:54

6道经典算法面试题

杨晶珍05-12 16:39

发评论

举报

0/150

取消