【java】synchronized 关键字

原创 2016年05月30日 16:12:32

大一的时候对这个东西敬而远之,可能是因为刚学java,完全不理解,现在是时候搞清楚它了。

字面意思是同步,翻译过来挺绕的。从同步和异步这对概念来入手,是比较难理解的。其实只要围绕“互斥”这个概念,synchronized关键字就很好理解!

大二操作系统会介绍互斥的概念,与java中的含义完全相同,只不过一个是操作系统中的,一个是java jvm的,应用层次不同而已。

1.我理解的java中的互斥是,在多线程环境下,对同一数据进行更新操作的互斥,也即只有当一个线程执行完更新后,另一个线程才可以开始。这也是synchronized关键字的用处。

举个例子,老生常谈了,存钱的例子。比如A的账户是100,现准备在atm中存入100,在这个过程中,A的朋友正在用手机银行,也试图往A的账户存入100。那么,在理论上就会有一个t1时刻,在t1时刻,atm机获取了A账户余额100,还未加100,同时A友的手机银行后台也获取了余额100,然后再各自进行加100的操作,更新A的账户,可想而知,A最后只有200,而非300。

问题出在对账户的更新必须互斥,atm在更新的时候,其他方式就必须等待,atm更新完了,才能开始其他的更新操作。这就是互斥。

2.锁的概念。这也是synchronized用法中的一个关键点。锁其实是互斥的标志。定义了哪些更新操作需要互斥。比如在A更新时,B的账户更新就不应该被阻塞,A和B的账户更新完全没有关系。而A的atm更新就应该和A的手机银行更新互斥。所以,锁定义了互斥的条件。


java中的锁

方法锁:

在非static方法上加synchronized关键字,那么同一个对象的所有的带有synchronized的方法全部互斥;锁就是调用的对象。所有的线程要想调用这个方法,必须拿到该对象的锁,锁只能被一个线程拥有。

块锁:

锁一段代码,需要指定锁是什么,可以是类锁可以使对象锁。块锁的优势是可以精确锁的范围,提高性能。

静态方法锁:

只能应用于静态方法,线程需要拿到类的锁才可以执行,不同对象也会被互斥。

例子:

package main;

public class Main {

	public static void main(String[] args) {
        new Main().f();
	}
	
	public void f(){
		final Acount acount1 = new Acount();
		for(int j=0;j<10;j++){
			Thread thread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					acount1.add1(100);
				}
			});
			thread.start();
		}
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("1结果: "+acount1.getMoney());
	}
}

package main;


public class Acount{

	private int money = 0;

	public synchronized void add(int inc){
		System.out.println("*********开始********");
		int temp = this.money;
		temp = temp + inc;
		this.money = temp;
		System.out.println(money);
		System.out.println("*********结束********");
	}
	
	public void add1(int inc){
		synchronized (this) {
			System.out.println("*********开始********");
			int temp = this.money;
			temp = temp + inc;
			this.money = temp;
			System.out.println(money);
			System.out.println("*********结束********");
		}
	}

	public int getMoney() {
		return money;
	}
}

最后打印结果的时候,需要等待的原因是打印语句执行时,可能之前的更新线程还未全部执行完毕。

推荐一篇很好的博客:http://www.cnblogs.com/paddix/p/5367116.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

Java并发编程---synchronized关键字

  • 2016年10月30日 16:26
  • 431KB
  • 下载

初学Java多线程:使用Synchronized关键字同步类方法

初学Java多线程:使用Synchronized关键字同步类方法 本文介绍使用Synchronized关键字同步类方法。要达成Java多线程的run方法同步,需要在void和public之间加上...
  • ihrthk
  • ihrthk
  • 2012年03月05日 10:54
  • 600

java多线程(五)synchronized关键字修饰代码块

在上一篇博客中我们介绍了

Java对象锁和类锁全面解析(多线程synchronized关键字)

最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念。最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没...

JAVA同步之 synchronized关键字详解

JAVA同步之 synchronized关键字详解

Java Runnable接口与synchronized关键字(同步方法)

一,概述通过Runable接口实现多线程比继承Thread接口要更实用一些,起码不会占用单继承的名额。在实现多线程时,还是需要注意同步的问题,下面一个具体的例子。二,简单的Runnable接口实现多线...

Java关键字synchronized使用总结

第一篇: 使用synchronized 在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题。在Java中内置了语言级的同步原语--synchronized,这也大大...

Java 多线程:synchronized 关键字用法(修饰类,方法,静态方法,代码块)

前言 在 多线程生成的原因(Java内存模型与i++操作解析) 中,介绍了Java的内存模型,从而可能导致的多线程问题。synchronized就是避免这个问题的解决方法之一。除了 synchr...

Java多线程之生产者消费者问题<一>:使用synchronized 关键字解决生产者消费者问题

今天看了一片博文,讲Java多线程之线程的协作,其中作者用程序实例说明了生产者和消费者问题,但我及其他读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的例子也都存在bug,经过仔细研究发现其中的问...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【java】synchronized 关键字
举报原因:
原因补充:

(最多只允许输入30个字)