public class ThreadDemo7{
//structs2线程不安全 共享变量
//n++ 复合操作 对于volatile修饰的变量不安全
//原子操作
int value; //让方法变成一个同步的方法
public synchronized int nextValue(){
return value ++;
}
public static void main(String[] args){
ThreadDemo7 t1 = new ThreadDemo7();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println(t1.nextValue() + " " + Thread.currentThread().getName());
}
}
}).start();
}
}
public class ThreadDemo7_1 {
private static volatile int num; //使用countDownLatch来等待使线程执行完
public static CountDownLatch countDownLatch = new CountDownLatch(); //由于n++是复合操作,所以并不能保证线程安全
//public synchronized int NextValue(){
public int NextValue(){
return num ++;
}
public static void main(String[] args){
ThreadDemo7_1 t1 = new ThreadDemo7_1(); for(int i=;i<;i++){
new Thread(new Runnable() {
@Override
public void run() {
for(int j=;j<;j++){
t1.NextValue();
}
countDownLatch.countDown();
}
}).start();
}
try{
countDownLatch.await();
}catch (InterruptedException e){
e.getMessage();
} System.out.println(num);
}
}
public class ThreadDemo7_2 {
private static AtomicInteger num = new AtomicInteger(); //使用countDownLatch来等待使线程执行完
public static CountDownLatch countDownLatch = new CountDownLatch(); public static void main(String[] args){
ThreadDemo7_1 t1 = new ThreadDemo7_1(); for(int i=;i<;i++){
new Thread(new Runnable() {
@Override
public void run() {
for(int j=;j<;j++){
num.incrementAndGet(); //原子性的num++,通过cas方式
}
countDownLatch.countDown();
}
}).start();
}
try{
countDownLatch.await();
}catch (InterruptedException e){
e.getMessage();
} System.out.println(num);
}
概念解析
并发机制依赖于JVM的实现和CPU的指令
1. volatile一般在多线程中使用,保证共享变量的可见性,解决并发带来的问题
可见性意思就是一个线程修改另外一个线程可以看到修改后的值,通过排它锁单独获得这个变量
volatile执行成本低,因为不会引起线程上下文的切换和调度
synchronized是重量级锁
2. volatile深层理解
有volatile变量修饰的共享变量进行读写操作的时候会多出第二行汇编代码
lock前缀的指令在多核处理器下会引发两件事情:
1)lock前缀指令会引起处理器缓存回写到内存
2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效
3. synchronized实现同步的基础:java中的每一个对象都可以作为锁
具体表现如下:
1)对于普通同步方法,锁是当前实例对象
2)对于静态同步方法,锁是当前类的class对象
3)对于同步方法块,锁是synchronized括号里配置的对象
当一个线程视图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁
Synchronized在JVM里的实现原理:JVM基于进入和退出Monitor对象来实现方法同步和代码块同步
2. 无锁,偏向锁,轻量级锁,重量级锁