synchronized使用场景及区别

参考syn锁:https://www.cnblogs.com/lixuwu/p/5676143.html

实例对象级别的锁和类对象级别的锁区别 一个锁的是类对象,一个锁的是实例对象。 若类对象被lock,则类对象的所有同步方法全被lock;

若实例对象被lock,则该实例对象的所有同步方法全被lock

  • 对象锁

1、实例对象级别的锁

private final Object lock = new Object();

public void demoMethod(){ synchronized (lock){ //other thread safe code } }

private Object lock = new Object();

public void demoMethod(){ synchronized (lock){ //other thread safe code } }

synchronized (this) { //other thread safe code }

2、类对象级别的锁

private final static Object lock = new Object();

public void demoMethod(){ synchronized (lock){ //other thread safe code } }

private static Object lock = new Object();

public void demoMethod(){ synchronized (lock){ //other thread safe code } }

类锁

synchronized (DemoClass.class){ //other thread saf

有如下例子:

package lockUtils.区别锁实例对象和类对象;

/**
 *
 * @when
 */
class MyThread implements Runnable {
    private TrySynLock trySynLock;
    private int num;

    public MyThread(TrySynLock trySynLock, int num) {
        this.trySynLock = trySynLock;
        this.num = num;
    }

    public void run() {
        while (true)
        {
            trySynLock.printNum(num);
            try {
                Thread.sleep(5*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

public class Test {


    public static void main(String[] args) {

        TrySynLock t = new TrySynLock();
        TrySynLock t1 = new TrySynLock();
        TrySynLock t2 = new TrySynLock();

        Thread a = new Thread(new MyThread(t, 1));
        Thread b = new Thread(new MyThread(t1, 2));
        Thread c = new Thread(new MyThread(t2, 3));

        a.start();
        b.start();
        c.start();
        /**
         * 结果
         * \Thread[Thread-0,5,main]0 1 2 3 4 5 Thread[Thread-1,5,main]0 1 2 6 7 8 3 4 5 6 7 8 9 10 11 12 13 14 9 10 11 12 13 14 15 16 17 18 15 16 17 19 20 21 22 23 24 18 19 20 21 22 23 24
         开始加锁:当前线程Thread[Thread-0,5,main]开始加锁:当前线程Thread[Thread-1,5,main]0 1 2 3 0 4 1 5 2 6 7 8 9 3
         4 5 6 7 8 9
         开始加锁:当前线程开始加锁:当前线程Thread[Thread-1,5,main]Thread[Thread-0,5,main]0 1 2 3 4 5 6 7 8 9
         0 1 2 3 4 5 6 7 8 9
         * 在上边的例子中试图使用这种方法达到互斥方法打印方法,但是事实是这样做是没有效果的,因为每个Trans对象都有自己的Object对象,
         * 这两个对象都有自己的锁,所以两个线程需要的是不同锁,两个锁之间没有任何相互作用,不会起到同步作用。
         * @when
         */

        /**
         * 上边的代码稍作修改就可以起到互斥作用,将Trans类中Object对象的声明改为下面这样:

            private static Object lock = new Object();
         * @when
         */
    }

}

2;

package lockUtils.区别锁实例对象和类对象;

public class TrySynLock {
    /**
     *实例对象级别的锁

     private final Object lock = new Object();

     public void demoMethod(){
     synchronized (lock){
     //other thread safe code
     }
     }
     synchronized (this) {
     //other thread safe code
     }

     类对象级别的锁

     private final static Object lock = new Object();
     public void demoMethod(){
     synchronized (lock){
     //other thread safe code
     }
     }

     private  static Object lock = new Object();
     public void demoMethod(){
     synchronized (lock){
     //other thread safe code
     }
     }
     * @when
     */
    /**
     *
     *
     *
     private Object lock = new Object();
     private static Object lock = new Object();
     private final Object lock = new Object();
     private static final Object lock = new Object();

     final:
     开始加锁:当前线程Thread[Thread-2,5,main]0 Thread[Thread-2,5,main]1 Thread[Thread-2,5,main]开始加锁:当前线程Thread[Thread-1,5,main]0 Thread[Thread-1,5,main]1 Thread[Thread-1,5,main]2 Thread[Thread-2,5,main]
     2 Thread[Thread-1,5,main]

     * @when
     */

    private static final Object lock = new Object();


    public void printNum(int num){
        synchronized (lock) {
            System.out.print("开始加锁:当前线程");
            System.out.print(Thread.currentThread());
            for(int i=0;i<3;i++){
                System.out.print(i+" "+Thread.currentThread());
            }
            System.out.println();
        }
    }
}

test.java

package lockUtils.区别锁实例对象和类对象;

/**
 *
 * @when
 */
class MyThread implements Runnable {
    private TrySynLock trySynLock;
    private int num;

    public MyThread(TrySynLock trySynLock, int num) {
        this.trySynLock = trySynLock;
        this.num = num;
    }

    public void run() {
        while (true)
        {
            trySynLock.printNum(num);
            try {
                Thread.sleep(5*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

public class Test {


    public static void main(String[] args) {

        TrySynLock t = new TrySynLock();
        TrySynLock t1 = new TrySynLock();
        TrySynLock t2 = new TrySynLock();

        Thread a = new Thread(new MyThread(t, 1));
        Thread b = new Thread(new MyThread(t1, 2));
        Thread c = new Thread(new MyThread(t2, 3));

        a.start();
        b.start();
        c.start();
        /**
         * 结果
         * \Thread[Thread-0,5,main]0 1 2 3 4 5 Thread[Thread-1,5,main]0 1 2 6 7 8 3 4 5 6 7 8 9 10 11 12 13 14 9 10 11 12 13 14 15 16 17 18 15 16 17 19 20 21 22 23 24 18 19 20 21 22 23 24
         开始加锁:当前线程Thread[Thread-0,5,main]开始加锁:当前线程Thread[Thread-1,5,main]0 1 2 3 0 4 1 5 2 6 7 8 9 3
         4 5 6 7 8 9
         开始加锁:当前线程开始加锁:当前线程Thread[Thread-1,5,main]Thread[Thread-0,5,main]0 1 2 3 4 5 6 7 8 9
         0 1 2 3 4 5 6 7 8 9
         * 在上边的例子中试图使用这种方法达到互斥方法打印方法,但是事实是这样做是没有效果的,因为每个Trans对象都有自己的Object对象,
         * 这两个对象都有自己的锁,所以两个线程需要的是不同锁,两个锁之间没有任何相互作用,不会起到同步作用。
         * @when
         */

        /**
         * 上边的代码稍作修改就可以起到互斥作用,将Trans类中Object对象的声明改为下面这样:

            private static Object lock = new Object();
         * @when
         */
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值