廖雪峰Java11多线程编程-2线程同步-2synchronized方法

2020-12-12 22:28

阅读:326

标签:val   技术   final   线程安全   成员   lda   value   get   end   

1.Java使用synchronized对一个方法进行加锁

class Counter{
    int count = 0;
    public synchronized void add(int n){
        count += n;
    }
    public synchronized void dec(int n){
        count -= n;
    }
    public int get(){//读取一个int类型是原子操作,不需要同步
        return count;
    }
}
class AddThread extends Thread {
    Counter counter;

    public AddThread(Counter counter) {
        this.counter = counter;
    }

    public void run() {
        for (int i = 0; i 

2.读取方法是否需要同步?

    public int get(){ //读取一个int类型是原子操作,不用同步
        return count;
    }
    public synchronized int[] get(){
        int[] result = new int[2];
        result[0] = this.value[0];
        result[1] = this.value[1];//读取万result[0],如果其他线程改变了result[1]的值,会导致读取的结果不一致。
        return result;
    }

所以,为了保险起见,读取方法通常也要同步。

3.线程安全与非线程安全

如果一个类被设计为允许多线程正确访问:

  • 这个类就是“线程安全”的(thread-safe),如java.lang.StringBuffer,其方法基本是synchronized
    技术图片
    线程安全的类:
  • 不变类:String,Integer,LocalDate。一旦创建,实际内部的成员变量无法改变,所以多线程只能读,不能写,不需要同步,就是安全的。
  • 没有成员变量的类:Math,这些工具类只提供了静态方法,没有成员变量。
  • 正确使用synchronized的类:StringBuffer

非线程安全的类:

  • 不能在多线程中共享实例并修改:ArrayList
  • 可以在多线程中以只读方式共享

4.总结:

  • 用synchronized修饰方法可以把整个方法变为同步代码块
  • synchronized方法加锁对象是this
  • 通过合理的设计和数据封装可以让一个类变为线程安全
  • 一个类没有特殊说明,默认不是thread-safe
  • 多线程能否访问某个非线程安全的实例,需要具体问题具体分析

廖雪峰Java11多线程编程-2线程同步-2synchronized方法

标签:val   技术   final   线程安全   成员   lda   value   get   end   

原文地址:https://www.cnblogs.com/csj2018/p/11001483.html


评论


亲,登录后才可以留言!