多线程的三大特性:
原子性:即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行
可见性:当多个线程访问一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
有序性:程序执行的顺序按照代码的先后顺序执行
多线程实现同步:
线程安全:当多个线程同时对共享的一个全局变量或者静态变量做写操作时,可能会发生数据冲突问题,也就是线程安全问题,但是做读操作是不会发生数据冲突问题
线程安全解决方法:使用多线程之间同步synchronized或者使用lock(锁)
同一时间只让当前一个线程进行对数据进行执行操作,当前线程执行完成后释放锁,才能让其他线程进行操作执行,避免了同时对数据的操作,这样的华就可以解决线程的不安全问题,也就是实现了数据的同步
synchronized两种用法:
第一种:将可能会发生线程安全问题的代码,给包括起来,称为同步代码块
第二种:在方法上修饰synchronized,称为同步函数
静态同步函数使用的锁是该函数所属字节码文件对象,可以使用getClass()方法获取,也可以用当前类名.class表示
同步的前提:
1.要有两个或者两个以上的线程,否则没有意义
2.多线程使用同一个锁
必须保证同步中只有一个线程运行
什么是Volatile?
volatile是java提供的一种同步手段,它是轻量级的同步,只能修饰变量,只能保证多线程的内存可见性,不能保证多线程的执行有序性。而最彻底的同步要保证有序性和可见性,例如synchronized。
任何被volatile修饰的变量,都不拷贝副本到工作内存,任何修改都会及时写在主存。因此对于volatile修饰的变量的修改,所有线程马上就能看到,但是volatile不能保证对变量的修改是有序的。
volatile与synchronized区别:
仅靠volatile不能保证线程的安全性,也就是原子性
①volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法。
②volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。
synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。
线程安全性:
线程安全性包括两个方面,①可见性。②原子性。
从上面可以看出:仅仅使用volatile并不能保证线程安全性。而synchronized则可实现线程的安全性。