美文网首页
线程安全性(二)

线程安全性(二)

作者: 墨平语凡 | 来源:发表于2018-06-02 09:27 被阅读0次

原子性 - 锁

原子性提供了互斥访问,同一时刻只能有一个线程对它进行操作。能保证同一时刻只有一个线程进行操作的,除了Atomic包之外还有。主要有

  • synchronized: 依赖JVM, 在这个关键字作用对象的作用范围内都是同一时刻只能由一个线程进行操作。
  • Lock: 代码层面的锁, 依赖特殊的CPU指令, 代码实现, ReentrantLock
锁.jpg

原子性-synchronized

  • 修饰代码块(被称为同步语句块):大括号括起来的代码,作用于调用的对象(调用这个代码块的对象)
  • 修饰方法(被称为同步方法): 整个方法, 作用于调用的对象
  • 修饰静态方法: 整个静态方法,作用于所有对象
  • 修饰类: 括号括起来的部分, 作用于所有对象 synchronized.jpg
package io.haitaoc.concurrency.example.sync;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * synchronized示例
 */
public class SynchronizedExample1 {

    public void test1(int j) {
        // 修饰一个代码块, 作用于当前调用对象,不同对象间不影响
        synchronized (this) {             // 作用范围是 大括号括起来的部分, 作用对象是调用这部分代码的对象
            for (int i = 0; i < 10; i++) {
                System.out.println("test1 - " + i+" "+j);
            }
        }                               // 作用范围结束
    }

    // 修饰一个方法, 作用于当前调用对象,不同对象间不影响
    public synchronized void test2(int j) {      // 作用范围是整个方法, 作用调用此方法的对象
        for (int i = 0; i < 10; i++) {
            System.out.println("test2 - " + i+" "+j);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample1 example1 = new SynchronizedExample1();
        SynchronizedExample1 example2 = new SynchronizedExample1();
        // 使用线程池, 相当于分别启动两个进程来执行test1()
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test2(1);
        });
        executorService.execute(()->{
            example2.test2(2);
        });
    }
}

如果一个方法内部是一个完整的同步代码块,那么它和用synchronized修饰这个方法时等同的。注意:如果SynchronizedExample1是父类,其子类在调用test1()test2()时是不包含synchronized的,原因在于synchronized不属于方法声明的一部分,如果子类想要使用synchronized,需要自己显示地在方法上进行声明

package io.haitaoc.concurrency.example.sync;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * synchronized示例
 */
public class SynchronizedExample2 {

    public static void test1(int j) {
        // 修饰一个类
        synchronized (SynchronizedExample2.class) {             // 作用范围是 大括号括起来的部分, 作用对象是调用这部分代码的对象
            for (int i = 0; i < 10; i++) {
                System.out.println("test1 - " + i+" "+j);
            }
        }                               // 作用范围结束
    }

    // 修饰一个静态方法, 作用于所有对象, 同一时刻只有一个线程可以执行
    public static synchronized void test2(int j) {      // 作用范围是整个方法, 作用调用此方法的对象
        for (int i = 0; i < 10; i++) {
            System.out.println("test2 - " + i+" "+j);
        }
    }

    public static void main(String[] args) {
        SynchronizedExample2 example1 = new SynchronizedExample2();
        SynchronizedExample2 example2 = new SynchronizedExample2();
        // 使用线程池, 相当于分别启动两个进程来执行test1()
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(()->{
            example1.test1(1);
        });
        executorService.execute(()->{
            example2.test1(2);
        });
        executorService.shutdown();
    }
}

修饰类的整个代码块和修饰静态方法时的作用效果相同

compare.jpg

相关文章

  • 线程安全性(二)

    原子性 - 锁 原子性提供了互斥访问,同一时刻只能有一个线程对它进行操作。能保证同一时刻只有一个线程进行操作的,除...

  • 线程安全性(二)

    原子性提供互斥访问,同一时刻只能有一个线程来对它进行操作 synchronized:依赖于JVM,属于不可中断锁,...

  • 二、线程安全性

    要编写线程安全的代码其核心在于要对状态访问操作进行管理,特别是对共享的(shared)和可变的(Mutable)状...

  • EffectiveJava第十章第五节

    线程安全性的文档化 并非出现synchronized关键字就是线程安全性文档化了。实际上,一个类支持的线程安全性有...

  • String的线程安全

    线程安全性 说道有关string的线程安全性,大家想到的肯定时stringbuffer和stringbuilder...

  • Java并发编程 线程安全性

    什么是线程安全性 线程安全性:当多个线程访问某个类时,不管运行时采用何种调度方式或者这些线程将被如何交替执行,并且...

  • java并发编程实战2~3

    2 线程安全性 2.1 什么是线程安全性 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何...

  • 谈谈并发编程中的线程安全性

    1. 线程安全性 在单线程程序中,我们并不需要去考虑线程的安全性。但是在多线程程序中,由于多个线程要共享相同的内存...

  • 线程安全性(一)

    参考线程安全性总结 CountDownLatchCountDownLatch 可以阻塞线程并保证线程在满足某种特定...

  • 高并发编程03 ~ 线程安全性

    这节我们讨论一个话题:线程安全性 一、概念 线程安全性:当多个线程同时访问某个资源的时候,不管环境采用何种调度方式...

网友评论

      本文标题:线程安全性(二)

      本文链接:https://www.haomeiwen.com/subject/yhecsftx.html