1. 可见性
可见性是指一个线程对共享变量的修改,对于另一个线程来说是否可见。
1.1 不可见问题
程序问题 : 女孩虽然知道结婚基金是十万,但是当基金的余额发生变化的时候,女孩无法知道最新的余额。
public class Money {
public static int money = 100000;
}
public class Girl extends Thread {
@Override
public void run() {
while(Money.money == 100000){
}
System.out.println("结婚基金已经不是十万了");
}
}
public class Boy extends Thread {
@Override
public void run() {
try {
Thread.sleep(10);
Money.money = 90000;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Demo {
public static void main(String[] args) {
Girl t1 = new Girl();
t1.setName("小路同学");
t1.start();
Boy t2 = new Boy();
t2.setName("小皮同学");
t2.start();
}
}
1.2 原因分析
1,堆内存是线程共享的,每一个线程都有自己隔离的本地内存(栈)。
2 ,每一个线程在使用堆里面变量的时候,都会先拷贝一份到变量的副本中。
3 ,在线程中,每一次使用是从变量的副本中获取的。

Volatile : 强制线程每次在使用的时候,都会看一下共享区域最新的值,从而可以解决上述问题。也就是说volatile能保证线程的可见性。
代码实现 :
public class Money {
public static volatile int money = 100000;
}
public class Girl extends Thread {
@Override
public void run() {
while(Money.money == 100000){
}
System.out.println("结婚基金已经不是十万了");
}
}
public class Boy extends Thread {
@Override
public void run() {
try {
Thread.sleep(10);
Money.money = 90000;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Demo {
public static void main(String[] args) {
Girl t1 = new Girl();
t1.setName("小路同学");
t1.start();
Boy t2 = new Boy();
t2.setName("小皮同学");
t2.start();
}
}
1.3 synchronized解决
synchronized解决 :
1 ,线程获得锁
2 ,清空变量副本
3 ,拷贝共享变量最新的值到变量副本中
4 ,执行代码
5 ,将修改后变量副本中的值赋值给共享数据
6 ,释放锁
所以说synchronized 也能保证线程的可见性。
代码实现 :
public class Money {
public static Object lock = new Object();
public static int money = 100000;
}
public class Girl extends Thread {
@Override
public void run() {
while(true){
synchronized (Money.lock){
if(Money.money != 100000){
System.out.println("结婚基金已经不是十万了");
break;
}
}
}
}
}
public class Boy extends Thread {
@Override
public void run() {
synchronized (Money.lock) {
try {
Thread.sleep(10);
Money.money = 90000;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Demo {
public static void main(String[] args) {
Girl t1 = new Girl();
t1.setName("小路同学");
t1.start();
Boy t2 = new Boy();
t2.setName("小皮同学");
t2.start();
}
}
2 原子性
原子性是指在一次操作或者多次操作中,要么所有的操作都成功,要么所有的操作都失败,多个操作是一个不可以分割的整体。
代码实现 :
public class AtomDemo {
public static void main(String[] args) {
MyAto

1万+

被折叠的 条评论
为什么被折叠?



