原子性
原子性是指一个操作或一组操作在执行过程中不可被中断,一个操作或者一组操作要么全部成功执行
问题代码
public class Test
{
static int count = 0;
public static void main( String[] args ) throws InterruptedException {
for (int i = 0; i < 11; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
increment();
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
decrement();
}
}).start();
}
Thread.sleep( 500);
System.out.println(count);
}
private static void increment( ){
count++;
}
public static void decrement( ){
count--;
}
}
实际输出值和期望值不一致
保障原子性-synchronized
public class Test
{
static final Object lock = new Object();
static int count = 0;
public static void main( String[] args ) throws InterruptedException {
for (int i = 0; i < 11; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
increment();
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
decrement();
}
}).start();
}
Thread.sleep( 500);
System.out.println(count);
Thread.sleep( 500);
System.out.println(count);
}
private static void increment( ){
synchronized (lock) {
count++;
}
}
public static void decrement( ){
synchronized (lock) {
count--;
}
}
}
保障原子性-Atomic类
public class Test
{
static AtomicInteger count = new AtomicInteger(0);
public static void main( String[] args ) throws InterruptedException {
for (int i = 0; i < 11; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
increment();
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
decrement();
}
}).start();
}
Thread.sleep( 500);
System.out.println(count);
Thread.sleep( 500);
System.out.println(count);
}
private static void increment( ){
count.incrementAndGet();
}
public static void decrement( ){
count.decrementAndGet();
}
}
ABA问题
public class Test
{
static AtomicReference<Integer> count = new AtomicReference<>(0);
public static void main( String[] args ) throws InterruptedException {
for (int i = 0; i < 11; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
increment();
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
decrement();
}
}).start();
}
Thread.sleep( 500);
System.out.println(count);
Thread.sleep( 500);
System.out.println(count);
}
private static void increment( ){
count.updateAndGet(v -> v + 1);
}
public static void decrement( ){
count.updateAndGet(v -> v - 1);
}
}
保障原子性-ReentrantLock
public class Test
{
static Integer count = 0;
static final ReentrantLock lock = new ReentrantLock();
public static void main( String[] args ) throws InterruptedException {
for (int i = 0; i < 11; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
increment();
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 1000; j++) {
decrement();
}
}).start();
}
Thread.sleep( 500);
System.out.println(count);
Thread.sleep( 500);
System.out.println(count);
}
private static void increment( ){
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public static void decrement( ){
lock.lock();
try {
count--;
} finally {
lock.unlock();
}
}
}
可见性
一个线程对另一个线程修改的变量是否能够看到
public class Test {
static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (flag){
// System.out.println("1111");
}
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
flag = false;
}).start();
Thread.sleep(200);
System.out.println("标记状态"+flag);
}
}
flag已经修改,但是程序不会结束
保障可见性-volatile
对公共变量加上volatile关键字
public class Test {
static volatile boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (flag){
}
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
flag = false;
}).start();
Thread.sleep(200);
System.out.println("标记状态"+flag);
}
}
保障可见性-synchronized
public class Test {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (flag){
synchronized(lock) {
}
}
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized(lock) { // 对 flag 加锁
flag = false;
}
}).start();
Thread.sleep(200);
System.out.println("标记状态"+flag);
}
}
如果synchronized在循环外出现锁被占用的情况,线程2修改标记无法执行
public class Test {
static boolean flag = true;
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
synchronized(lock) {
while (flag){
}
}
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized(lock) { // 对 flag 加锁
flag = false;
}
}).start();
Thread.sleep(500);
System.out.println("标记状态"+flag);
}
}
保障可见性-Lock
public class Test {
static boolean flag = true;
private static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (flag){
lock.lock();
try{
}finally {
lock.unlock();
}
}
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
lock.lock();
try{
flag = false;
}finally {
lock.unlock();
}
}).start();
Thread.sleep(200);
System.out.println("标记状态"+flag);
}
}
有序性
public class Test {
static int count = 0;
static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
count = 0;
flag = false;
Thread t1 = new Thread(() -> {
if (flag) {
count += count;
} else {
count = 1;
}
});
Thread t2 = new Thread(() -> {
count = count+5 ;
flag = true;
});
t1.start();
t2.start();
t1.join();
t2.join();
//1、如果先执行t1,flag = false count = 1
// 再执行 count = 1+5 = 6,将flag赋值为true
//2、如果先执行t2,count = 0+5,将true转变成true
// 再执行t2,count 就变成了10
if (count == 1) {
System.out.println("第" + i + "次循环 count = " + count + " flag=" + flag);
}
}
}
}
执行出来会出现先执行了线程1的count=1,再执行flag=true
保障有序性-volatile+Lock
public class Test {
static volatile int count = 0;
static volatile boolean flag = false;
private static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
count = 0;
flag = false;
Thread t1 = new Thread(() -> {
lock.lock();
try {
if (flag) {
count += count;
} else {
count = 1;
}
} finally {
lock.unlock();
}
});
Thread t2 = new Thread(() -> {
lock.lock();
try {
count = count+5 ;
flag = true;
} finally {
lock.unlock();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
//1、如果先执行t1,flag = false count = 1
// 再执行 count = 1+5 = 6,将flag赋值为true
//2、如果先执行t2,count = 0+5,将true转变成true
// 再执行t2,count 就变成了10
if (count == 1) {
System.out.println("第" + i + "次循环 count = " + count + " flag=" + flag);
}
}
System.out.println("执行结束");
}
}