原子性 - 锁
原子性:互斥性。能保证同一时刻只有一个线程操作的,除了atomic包内的类,另个锁。
锁:
synchronized, 锁关键字,依赖jvm实现,这个关键字作用对象的作用范围内,同一时刻只能有一个线程操作的,
Lock:依赖特殊的cpu指令,代码实现,ReentrantLock
synchronized
synchronized同步锁,修饰4中对象
(1)修饰一个代码块,被修饰的范围叫做同步语句块,作用于调用对象,同一个对象调用是互斥的;
代码演示:
package com.mmall.concurrency.sync;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;
/**
* @Author: wn
* @Description: synchronized ,
* @Date: Created in 2019/1/12 15:05
*/
@Slf4j
public class SynchronizedExample1 {
// 修饰一个代码块,被修饰的范围叫做同步语句块,作用于调用对象
public void test1() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
log.info("test1 {}", i);
}
}
}
// 修饰一个方法,,被修饰的范围叫做同步方法,作用于调用对象
public synchronized void test2() {
for (int i = 0; i < 10; i++) {
log.info("test2 {}", i);
}
}
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = new ThreadPoolExecutor(2, 5, 3000,
TimeUnit.MINUTES, new LinkedBlockingDeque<>(), new ThreadPoolExecutor.AbortPolicy());
// log.info("修饰一个代码块,被修饰的范围叫做同步语句块,作用于调用对象,同一个对象调用是互斥的:");
// executorService.execute(() -> {
// example1.test1();
// });
// executorService.execute(() -> {
// example1.test1();
// });
log.info("修饰一个方法,,被修饰的范围叫做同步方法,作用于调用对象,同一个对象调用是互斥的:");
executorService.execute(() -> {
example1.test2();
});
executorService.execute(() -> {
example1.test2();
});
// log.info("调用不同的代码块,各自执行,互不影响");
// executorService.execute(() -> {
// example1.test1(1);
// });
// executorService.execute(() -> {
// example2.test2(2);
// });
}
}
执行结果:
(2) 修饰一个方法,,被修饰的范围叫做同步方法,作用于调用对象,同一个对象调用是互斥的
执行结果:
(3)修饰一个类,作用对象是类的所有对象
运行结果:
(4)修饰一个静态方法,被修饰的范围叫做静态同步方法,作用对象是类的所有对象
运行结果:
synchronize 实现计数器
执行结果:
5000
原子性 - 对比 锁区别
synchronize :不可中断,一旦执行到同步代码时,就必须执行完,适合竞争不激烈的情况,可读性较好,当竞争很激烈时,synchronize 的性能下降非常快
Lock:可中断,调用unlock()可以中断线程执行,竞争激烈时保持常态,
atomic : 竞争激烈时也能维持常态,比Lock 性能好,缺点就是只能同步一个值