该关键字可用来保障原子性、可见性和有序性
多个线程的情况下,各个线程的变量为其私有,互不影响
在被调用方法前加synchronized关键字上锁
方法中使用synchronized实现同步的原因是使用了flag标记ACC_SYNCHRONIZED,当调用方法时,会先检查其是否设置没如果设置了则执行线程先持有同步锁,再执行方法,最后在方法完成时释放锁。
如果使用synchronized代码块,则使用monitorenter和monitorexit指令进行同步处理。
如果多个线程的业务对象不一样,则他们的锁是单独的,并不存在争夺关系
synchronized是锁对象,并非锁方法,只有拿到锁的线程才能调用该对象中所有的synchronized方法
在setValue()和getValue()设置synchronized关键字解决。
如果一个线程获得了一个对象的锁,在没有释放的情况下这个线程还可以再次获取该对象的锁
当存在父子类继承关系时,自雷是完全可以通过锁重入调用父类的同步方法
当一个线程执行的代码出现异常时,其所持有的锁会自动释放。
如果重写方法不使用synchronized则是非同步方法,使用的话则是同步方法
当currentThread在指定的对象上保持锁定时才返回true
synchronized代码块是将任意对象作为锁,可以将锁看做一个标识,哪个线程持有这个标识,就可以执行同步方法。
会导致某些不必要的时间浪费
两个并发线程访问同一个对象object中的synchronized(this)同步代码块时,只能同步运行。
只将重要代码放入synchronized(this)同步代码块中
不在synchronized块中就是异步执行,在synchronized块中就是同步执行。
同一个对象的synchronized对所有的线程使用的锁是同一个(对象监视器是同一个)
synchronized和synchronized(this)同步代码块会将本类中其他的同步方法和同步代码块调用呈同步效果,同一时间只有赢线程可以执行同步方法或同步代码块中的代码。
在关键部分添加synchronized(this)同步代码块解决
每一个*.java文件对应的Class类的实例都是一个,在内存中是单例的。
加在静态方法上的方式是将类对应Class类的对象作为锁,加在非静态方法上是将方法所在的类的对象作为锁,这两个不是同一把锁
同步synchronized(class)代码块的作用和synchronized static方法的作用一样
如果以String常量作为锁的话,可能会导致多个线程的锁是同一个。可以通过new String()或者new Object()创建不同的对象
可以用同步块解决问题
只要两个线程互相等待对方释放锁,就可能导致死锁。
新建内部类
(要用到类的实例对象myClass)
InnerClass innerClass = myClass.new InnerClass();
新建静态内部类
InnerClass innerClass = new InnerClass();
如果持有不同的锁,他们则是异步的
1.可见性
2.原子性
3.禁止代码重排序
volatile关键字可以强制从公共内存中读取变量的值
synchronized代码块具有增加可见性的作用,synchronized关键字可以使多个线程访问同一个资源具有同步性,而且具有使线程工作内存中的私有变量与公共内存中的变量同步的特性
使用volatile解决在32位系统中long或double数据类型写操作为非原子的情况。
volatile不适合处理i++操作,其是非原子操作,非线程安全的。
使用Atomic原子类进行i++操作实现原子性,如AtomicInteger
可以用synchronized关键字解决方法之间调用不同步的问题
使用volatile和synchronized关键字可以禁止代码重排序
volatile之前和之后的代码可以重排
volatile之前的代码不可以重排到volatile之后
volatile之后的代码不可以重排到volatile之前
synchronized之前的代码不可以重排到synchronized之后
synchronized之后的代码不可以重排到synchronized之前