一、synchronize概念
1、官方:同步方法支持一种简单的策略来防止线程受到干扰和内存一致性错误;如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成。
2通俗理解:能够保证在同一时刻最多只有一个线程执行该段代码以达到保证并发安全的效果。一段代码被synchronize关键字修饰了,那么被修饰的代码了就会以原子的方式执行,而多个线程执行这个的时候他们不会相互干扰不会相互影响;因为多个线程之间不会同时执行,只要不同时执行就不会出现并发问题。那它们是这样做到不同时执行了,又是这样知道你在执行我就不执行了?是因为它们有一把锁,当第一个线程运行时它就拿到这把锁、独占这把锁它运行完成或一定的条件了它才释放这把锁,其他的线程只能是等待或堵塞状态直到轮到它了才可以拿到锁。synchronize关键字就是通过这种方式来完成了安全并发保护的工作。
二、synchronize的地位
1、synchronize是Java的关键字,被Java语言原生支持。
2、是最基础的互斥同步手段。
3、是并发编程中的元老级角色,是并发编程的必学内容。
三、不使用并发手段会有什么后果?
场景:两条线程同时执行a++十万次。最后的结果应该是二十万次。
package com.zy.san.synSan;
/**
*
* @author Administrator 消失的请求
*/
public class DisappearRequest1 implements Runnable {
static DisappearRequest1 instance = new DisappearRequest1();
public static void main(String[] args) throws Exception {
Thread th = new Thread(instance);
Thread th2 = new Thread(instance);
th.start();
th2.start();
th.join();
th2.join();
System.out.println(a);
}
static int a = 0;
public void run() {
for (int i = 0; i < 100000; i++) {
a++;
}
}
}
运行结果应该是2十万次才对,为什么会比我们预测的少了
看a++这一行代码,看似一行代码实则有三步
1、读取a
2、a加一
3、存入a的数据
没有synchronize,执行上面的任何一步都会被打断。所以结果会少就不奇怪了。
四、处理方法:
1、对象锁的方法锁:
public synchronized void run() {
for (int i = 0; i < 100000; i++) {
a++;
}
2、对象锁的同步代码块:
public void run() {
synchronized(this){
for (int i = 0; i < 100000; i++) {
a++;
}
}
3、类锁的static模式:
static DisappearRequest1 instance = new DisappearRequest1();
static DisappearRequest1 instance2 = new DisappearRequest1();
public static void main(String[] args) throws Exception {
Thread th = new Thread(instance);
Thread th2 = new Thread(instance2);
th.start();
th2.start();
while (th.isAlive() || th2.isAlive()) {
}
System.out.println(a);
}
static int a = 0;
public void run() {
for (int i = 0; i < 100000; i++) {
method();
}
}
private synchronized void method() {
a++;
}
4、类锁的synchronize(*.class)模式:
Thread th = new Thread(instance);
Thread th2 = new Thread(instance2);
th.start();
th2.start();
while (th.isAlive() || th2.isAlive()) {
}
System.out.println(a);
}
static int a = 0;
public void run() {
for (int i = 0; i < 100000; i++) {
method();
}
}
private void method() {
synchronized (DisappearRequest1.class) {
a++;
}
}