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编辑  收藏  举报

导航