关于对象锁和类锁

相关说明:

  • 类锁控制类的所有实例的访问
  • 对象锁锁住的是当前实例,对同一类的不同实例就没有限制

实验环节:
对象锁

class Object_Lock{
    //代码块上 -- 锁住调用该方法的对象
    public void funA(){
        synchronized (Object_Lock.this){
            for(int i = 1 ;i <=5;i++){
                System.out.println(Thread.currentThread().getName()+"这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>"+i);
            }
        }
    }
    Object object =new Object();
    //代码块上 -- 锁住任何一个对象
    public void funB(){
        synchronized (object){
            for(int i = 1 ;i <=5;i++){
                System.out.println(Thread.currentThread().getName()+"这是一个用在代码块上的对象锁(锁住任何一个对象)>>>"+i);
            }
        }
    }
    //方法上
    public synchronized void funC(){
        for(int i = 1 ;i <=5;i++){
            System.out.println(Thread.currentThread().getName()+"这是一个用在方法上的对象锁>>>"+i);
        }
    }
}

实验1:测试`代码块上锁住调用该方法的对象
a)一个类的不同实例、

 public void test1(){
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Object_Lock o1 = new Object_Lock();
                o1.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Object_Lock o2 = new Object_Lock();
                o2.funA();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实现结果:没有互斥地访问

Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5

b)同一个类的同一实例

public void test2(){
        Object_Lock o = new Object_Lock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funA();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实验结果:互斥地访问

Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread2这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5

实验2:测试锁住调用方法的对象和锁住其他对象

 public void test3(){
        Object_Lock o = new Object_Lock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funB();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实验结果:锁住的对象不同,不互斥

Thread2这是一个用在代码块上的对象锁(锁住任何一个对象)>>>1
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread2这是一个用在代码块上的对象锁(锁住任何一个对象)>>>2
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread2这是一个用在代码块上的对象锁(锁住任何一个对象)>>>3
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5
Thread2这是一个用在代码块上的对象锁(锁住任何一个对象)>>>4
Thread2这是一个用在代码块上的对象锁(锁住任何一个对象)>>>5

实验3:测试方法和代码块

public void test4(){
        Object_Lock o = new Object_Lock();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                o.funC();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实验结果:锁住的是同一对象,互斥

Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>1
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>2
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>3
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>4
Thread1这是一个用在代码块上的对象锁(锁住调用该方法的对象)>>>5
Thread2这是一个用在方法上的对象锁>>>1
Thread2这是一个用在方法上的对象锁>>>2
Thread2这是一个用在方法上的对象锁>>>3
Thread2这是一个用在方法上的对象锁>>>4
Thread2这是一个用在方法上的对象锁>>>5

类锁:
控制类的所有实例的访问。

//类锁 : 控制类的所有实例的访问,当一个线程获取类锁时,其他线程必须等待
class Class_Lock{
    //代码块上
    public void funA(){
        synchronized (Class_Lock.class){
            for(int i = 1;i<=5;i++){
                System.out.println(Thread.currentThread().getName()+"这是一个用在代码块上的类锁>>>"+i);
            }
        }
    }
    //static synchronized
    //代码块上
    public static synchronized void funB(){
        for(int i = 1;i<=5;i++){
            System.out.println(Thread.currentThread().getName()+"这是一个用在方法上的类锁>>>"+i);
        }
    }
}

实验1:不同类的实例访问代码块锁

 public void test5(){
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Class_Lock c1 = new Class_Lock();
                c1.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Class_Lock c2 = new Class_Lock();
                c2.funA();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实验结果:互斥

Thread1这是一个用在代码块上的类锁>>>1
Thread1这是一个用在代码块上的类锁>>>2
Thread1这是一个用在代码块上的类锁>>>3
Thread1这是一个用在代码块上的类锁>>>4
Thread1这是一个用在代码块上的类锁>>>5
Thread2这是一个用在代码块上的类锁>>>1
Thread2这是一个用在代码块上的类锁>>>2
Thread2这是一个用在代码块上的类锁>>>3
Thread2这是一个用在代码块上的类锁>>>4
Thread2这是一个用在代码块上的类锁>>>5

实验2:不同类的实例访问代码块锁和static方法锁

public void test6(){
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                Class_Lock c1 = new Class_Lock();
                c1.funA();
            }
        },"Thread1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                Class_Lock c2 = new Class_Lock();
                c2.funB();
            }
        },"Thread2");
        thread1.start();
        thread2.start();
    }

实验结果:互斥

Thread1这是一个用在代码块上的类锁>>>1
Thread1这是一个用在代码块上的类锁>>>2
Thread1这是一个用在代码块上的类锁>>>3
Thread1这是一个用在代码块上的类锁>>>4
Thread1这是一个用在代码块上的类锁>>>5
Thread2这是一个用在方法上的类锁>>>1
Thread2这是一个用在方法上的类锁>>>2
Thread2这是一个用在方法上的类锁>>>3
Thread2这是一个用在方法上的类锁>>>4
Thread2这是一个用在方法上的类锁>>>5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值