volatile特性:
1.保证可见性
2.不保证原子性
3.禁止指令重排
如下代码所示
package com.example.starter;
public class VolatileDemo {
public static void main(String[] args) throws InterruptedException {
Mydata data = new Mydata();
for (int i = 1; i <= 20 ; i++) {
new Thread(()->{
for (int j = 1; j <= 1000; j++) {
//不保证原子性
data.add();
}
}).start();
}
while(Thread.activeCount() > 2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"----int type finally result number:"+ data.number);
}
}
class Mydata{
volatile int number = 0;
public void add60(){
this.number = 60;
}
public void add(){
number ++;
}
public void decue(){
this.number --;
}
}
结果:正常结果应该是20000 但这种方式永远不会输出20000。如何保证原子行呢,使用synchronized
如下代码所示:
package com.example.starter;
public class VolatileDemo {
public static void main(String[] args) throws InterruptedException {
Mydata data = new Mydata();
for (int i = 1; i <= 20 ; i++) {
new Thread(()->{
for (int j = 1; j <= 1000; j++) {
//不保证原子性
data.add();
}
}).start();
}
while(Thread.activeCount() > 2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"----int type finally result number:"+ data.number);
}
}
class Mydata{
volatile int number = 0;
public void add60(){
this.number = 60;
}
public synchronized void add(){
number ++;
}
public void decue(){
this.number --;
}
}
输出:
思考:使用synchronized太重量级了,会使我们的线程同步执行,多线程模式下大量线程排对阻塞,影响性能
优化:使用atomicInteger
如下代码所示
package com.example.starter;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDemo {
public static void main(String[] args) throws InterruptedException {
Mydata1 data = new Mydata1();
for (int i = 1; i <= 20 ; i++) {
new Thread(()->{
for (int j = 1; j <= 1000; j++) {
//不保证原子性
data.add();
//保证原子性
data.addAtomic();
}
}).start();
}
while(Thread.activeCount() > 2){
Thread.yield();
}
System.out.println(Thread.currentThread().getName()+"----int type finally result number:"+ data.number);
System.out.println(Thread.currentThread().getName()+"----atomic type finally result atomicInteger:"+ data.atomicInteger);
}
}
class Mydata1{
volatile int number = 0;
public void add60(){
this.number = 60;
}
public void add(){
number ++;
}
public void decue(){
this.number --;
}
AtomicInteger atomicInteger = new AtomicInteger();
public void addAtomic(){
atomicInteger.getAndIncrement();
}
}
结果