synchronized锁

前言:

    在程序中,若存在多个线程同时操作共享变量,就会造成线程不安全,要保证多线程操作共享数据安全,必须加上互斥锁,同一时刻只有一个线程可以操作数据。


synchronized三种用法:

    1.实例方法

    2.静态方法

    3.代码块

我们先写出代码,查看运行结果,然后再分析

1.实例方法

package com.xhx.java;

/**
 * xuhaixing
 * 2018/6/30 17:29
 **/
public class SynchronizedMethod {
    public synchronized void method1(){
        System.out.println("method1--start");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method1--end");
    }
    public synchronized void method2(){
        System.out.println("method2--start");
        System.out.println("method2--end");
    }

    public static void main(String[] args) {
        final SynchronizedMethod sync = new SynchronizedMethod();
        new Thread(() -> sync.method1()).start();
        new Thread(() -> sync.method2()).start();
    }
    /**
     * method1--start
     * method1--end
     * method2--start
     * method2--end
     */
}

可以看出,对于同一个实例,方法的执行也是互斥的,锁的时当前实例对象


2.静态方法

package com.xhx.java;

/**
 * xuhaixing
 * 2018/6/30 17:29
 **/
public class SynchronizedStaticMethod {
    public static synchronized void method1(){
        System.out.println("method1--start");
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method1--end");
    }
    public static synchronized void method2(){
        System.out.println("method2--start");
        System.out.println("method2--end");
    }

    public static void main(String[] args) {
        new Thread(() ->
                SynchronizedStaticMethod.method1()).start();
        new Thread(() ->
                SynchronizedStaticMethod.method2()).start();
    }
    /**
     * method1--start
     * method1--end
     * method2--start
     * method2--end
     */
}

类中的静态方法执行也是互斥的,锁的是Class


3.代码块

package com.xhx.java;

/**
 * xuhaixing
 * 2018/6/30 17:29
 **/
public class SynchronizedBlock {
    public void method1() {
        System.out.println("method1--start");
        try {
            synchronized (this) {
                System.out.println("method1--executing");
                Thread.sleep(3000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("method1--end");
    }

    public void method2() {
        System.out.println("method2--start");
        synchronized (this) {
            System.out.println("method2--executing");
        }
        System.out.println("method2--end");
    }

    public static void main(String[] args) {
        final SynchronizedBlock sync = new SynchronizedBlock();
        new Thread(() -> sync.method1()).start();
        new Thread(() -> sync.method2()).start();
    }
    /**
     method1--start
     method1--executing
     method2--start
     method1--end
     method2--executing
     method2--end
     */
}

执行到锁时,因为锁的都是this,所以代码块也是互斥的



有一种情况需要注意,如果线程A访问静态的synchronized方法,线程B访问非静态的synchronized方法,是允许的,因为它俩用的不是同一个锁。

在使用synchronized的时候,尽量降低加锁范围,能在代码段上加锁,就不要在方法上加锁。synchronized内部通过monitor来实现的,属于重量级锁。



我的github代码地址


猜你喜欢

转载自blog.csdn.net/u012326462/article/details/80868725