线程安全性之原子性——synchronized关键字

线程安全性之原子性——synchronized关键字

synchronized是java的一个关键字,是依赖JVM来实现锁。在这个关键字的作用对象的作用范围内,都只能有一个线程来执行

我们来看一下synchronized关键字的作用范围。他有四种作用范围
在这里插入图片描述下面我将给出4中范围的代码模拟过程
先看前两种,修饰代码块和方法

@Slf4j
public class SynchronizedExample1 {
    private static Logger log=LoggerFactory.getLogger(SynchronizedExample1.class);

    /**
     * 用synchronized修饰一个代码块,则作用的是它括号里的代码,作用的对象是调用这部分代码的对象
     * 被修饰的代码被称作是同步语句块,
     * 结果是两个进程可以交替执行
     */
    private void test1(int j){
        synchronized (this){
            for(int i=0;i<10;i++){
                log.info("test1-{} {}",j,i);
            }
        }
    }
    /**
     * 用synchronized修饰一个方法,把关键字放到方法名中
     * 作用的对象是调用这部分代码的对象
     * 结果是两个进程可以交替执行
     */
    public synchronized void test2(int j){
        for(int i=0;i<10;i++){
            log.info("test2-{} {}",j,i);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample1 example1=new SynchronizedExample1();
        SynchronizedExample1 example2=new SynchronizedExample1();
        ExecutorService executorService= Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test2(1);
        });
        executorService.execute(()->{
            example2.test2(2);
        });
    }
}

yunxins我们先来测试一下修饰一个方法,即test2,运行结果来看一下
在这里插入图片描述我们发现两个类的对象可以交替执行test2的方法。
我们来测试一下修饰一个代码块,即执行test1方法
结果发现,和上面运行结果基本一致,都是交替执行方法。
下面我们来看一下测试一个类和测试一个静态方法。

@Slf4j
public class SynchronizedExample2 {
    private static Logger log=LoggerFactory.getLogger(SynchronizedExample2.class);

    /**
     * 用synchronized修饰一个类
     * 此时,同一个时间,只有一个线程可以被执行
     */
    private static void test1(int j){
        synchronized (SynchronizedExample2.class){
            for(int i=0;i<10;i++){
                log.info("test1-{} {}",j,i);
            }
        }
    }
    /**
     * 用synchronized修饰一个静态方法,把关键字放到方法名中
     * 作用的对象是调用这部分代码的对象
     * 此时,同一个时间,只有一个线程可以被执行
     */
    public static synchronized void test2(int j){
        for(int i=0;i<10;i++){
            log.info("test2-{} {}",j,i);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample2 example1=new SynchronizedExample2();
        SynchronizedExample2 example2=new SynchronizedExample2();
        ExecutorService executorService= Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test1(1);
        });
        executorService.execute(()->{
            example2.test1(2);
        });
    }
}

先测试一下test1方法,打印结果
在这里插入图片描述此时发现,两个实例化的对象并不是交替执行,而是只让一个对象执行完之后另一个对象才执行。
用synchronized修饰一个静态方法时和它一样,也是先执行完一个对象的操作,在执行另一个对象 的操作。

猜你喜欢

转载自blog.csdn.net/ning1994724/article/details/84995220
今日推荐