看多线程的相关书籍的时候,会常常阅读到一个使用前景,就是银行的取钱存钱操做。
假设咱们使用两个线程来模拟取钱操做,模拟两我的使用同一个帐户并发取钱的问题,咱们都知道存款不可能为负的,
可是每每并发操做的时候,可能就会致使系统出错致使出现负的数字(假设一开始都是200元余额,两边同时操做取出150,系统可能就会出错)。
出现相似这种问题就是缺乏同步安全性,为了解决这个问题,Java就增进了同步监视器来解决这个,也就是本文讲的synchronized的做用。安全
synchronized是Java中的关键字。同步的意思,用在解决线程安全问题上。有添加在方法上,和直接修饰代码块。有种保护的做用,使用修饰以后,家门上了锁,别人进不来。用synchronized修饰的方法只容许一个线程执行,其余线程没法进入该方法。(原子性操做),银行使用该操做以后,就会变成一个排队操做同样,像前言的例子,就会变成一我的等另外一个操做取出150以后才能够取钱,这样就不会出现负的余额。多线程
因此synchronized保护的是线程遭受破坏,必须按照容许的权限进行资源访问。
记得synchronized关键字能够修饰方法,能够修饰代码块,但不能修饰构造函数、属性等。并发
//long与double的操做不是原子的
//synchronized代码块 //obj对象即表示线程开始执行同步代码块以前,必须先得到对同步监视器的锁定 //步骤:加锁--修改--释放锁 synchronized (obj) { ... }
任什么时候刻只能有一个线程能够得到对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对该同步监视器的锁定。具体的格式参见上面。函数
//synchronized方法,能够分为静态方法和普通方法 synchronized void method(){ ... } //等价于 public void method() { synchronized(this) { // todo } } //不管哪一种形式均可以看作是“{”处获取锁,“}”释放锁
与同步代码块对应,Java 的多线程安全支持还提供了同步方法,同步方法就是使用synchronized关键字来修饰某个方法(放在权限词的后面便可),则该方法称为同步方法。对于同步方法而言,无须显式指定同步监视器,同步方法的同步监视器是this,也就是该对象自己。在格式上能够看到一些用法,可是具体来说,synchronized用在方法体上还分为用在普通方法和静态方法两种,区别在做用锁对象的不一样。工具
修饰普通方法做用的是调用这个方法的对象,修饰静态方法做用是调用这个类的全部对象。 synchronized static方法能够在类的范围内防止对static数据的并发访问,
使用同步方法能够很方便得实现线程安全的类,这样类的对象能够被多个线程同时安全得访问。学习
关于什么使用同步,也就是上锁,引用书上的话this
若是你在写一个变量,它可能接下来将被另外一个线程读取,或者正在读取上一个已经被另外一个线程写过的变量,那么你必须使用同步,而且,读取线程都必须用相同的监视器锁同步线程
——Brain Goetz《Java Concurrency in Pactice》的做者code
我的学习记录,有错误欢迎指点,谢谢!加油!