Java多线程系列3 synchronized 关键词
先来看一个线程安全的例子 ,两个线程对count进行累加,共累加10万次。
public class AddTest { public static void main(String[] args) { MyAddRunnable addRunnable = new MyAddRunnable(); Thread thread1 = new Thread(addRunnable); Thread thread2 = new Thread(addRunnable); thread1.start(); thread2.start(); try { thread1.join(); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(addRunnable.count); } } class MyAddRunnable implements Runnable { public int count = 0; @Override public void run() { for (int i = 0; i < 100000; i++) { count++; } } }
随便运行多少次这个程序,都得不到正确的结果 200000
于是乎 引出今天的问题,线程安全问题。
怎么解决呢,有多种解决方法,现在来说2种,
第一种 在 Add 类的 run方法上 加synchronized
第二种 使用无锁的类
public class AtomicIntTest { public static void main(String[] args) { AddRunnable addRunnable = new AddRunnable(); Thread myThread1 = new Thread(addRunnable); Thread myThread2 = new Thread(addRunnable); myThread1.start(); myThread2.start(); try { myThread1.join(); myThread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(addRunnable.count); } } class AddRunnable implements Runnable { AtomicInteger count = new AtomicInteger(); @Override public void run() { for (int i = 0; i < 100000; i++) { count.incrementAndGet(); } } }
synchronized 关键词 详解
方法上(对象锁) 比如在某个对象的方法上加锁,如果哪个线程先执行到synchronized 的代码块 相当于 持有了该方法所属对象的锁
静态方法 表示锁定 .class类 ,类一级别的锁,独占(.class类)
同步代码块
解决线程安全问题其实只需限制对共享资源访问的不确定性即可。使用同步方法时,使得整个方法体都成为了同步执行状态,会使得可能出现同步范围 过大的情况,于是,我们可以针对需要同步的代码可以直接另一种同步方式——同步代码块来解决。
实际开发中,也不太建议直接在方法上加锁,只加在需要同步的地方就好。
同步代码块的格式为:
synchronized (obj) {
//...
}
一定要注意:必须锁住的是同一个对象才可以。。。。
synchronized修饰普通方法或者synchronized(this)获取的是对象锁 调用该对象的同步方法会阻塞
synchronized 静态方法,或者synchronized(this.getClass())这样的写法,就相当于全局锁,和对象实例无关。
synchronized(obj)锁住的是括号中的对象,如果不是同一个对象则不会阻塞。
posted on 2017-05-09 23:39 一只小蜗牛12138 阅读(130) 评论(0) 编辑 收藏 举报