廖雪峰Java11多线程编程-2线程同步-2synchronized方法
Posted csj2018
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了廖雪峰Java11多线程编程-2线程同步-2synchronized方法相关的知识,希望对你有一定的参考价值。
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 < Main.LOOP; i++)
counter.add(1);
class DecThread extends Thread
Counter counter;
public DecThread(Counter counter)
this.counter = counter;
public void run()
for(int i=0;i<Main.LOOP;i++)
counter.dec(1);
public class Main
static final int LOOP=10000;
public static void main(String[] args) throws InterruptedException
Counter counter = new Counter();
Thread t1 = new AddThread(counter);
Thread t2 = new DecThread(counter);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(counter.get());
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方法的主要内容,如果未能解决你的问题,请参考以下文章
廖雪峰Java11多线程编程-4线程工具类-1ThreadLocal
廖雪峰Java11多线程编程-3高级concurrent包-5Atomic