解决下面这个并发问题
public class MainActivity extends AppCompatActivity {
private int i = 60000;//共享变量,库存60000
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
test();
}
public void order() {
i--; //减库存
}
//模拟高并发的业务场景
public void test() {
try {
for (int j = 0; j < 6; j++) {
new Thread() {
@Override
public void run() {
super.run();
for (int k = 0; k < 10000; k++) {
order();
}
}
}.start();
}
Thread.sleep(3000);
System.out.println("库存量" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2021-03-26 10:29:23.697 17364-17364/com.example.myapplication I/System.out: 库存量2599
1.内置锁synchronized
public class MainActivity extends AppCompatActivity {
private int i = 60000;//共享变量,库存60000
private Object o= new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
test();
}
public void order() {
synchronized (o){
i--; //减库存
}
}
}
2021-03-26 10:33:28.340 17524-17524/com.example.myapplication I/System.out: 库存量0
2.乐观锁
执行速度比synchronized快很多的,碰到复杂功能的时候就完不成功能了
public class MainActivity extends AppCompatActivity {
AtomicInteger i = new AtomicInteger(60000);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
test();
}
public void order() {
i.decrementAndGet();
}
//模拟高并发的业务场景
public void test() {
try {
for (int j = 0; j < 6; j++) {
new Thread() {
@Override
public void run() {
super.run();
for (int k = 0; k < 10000; k++) {
order();
}
}
}.start();
}
Thread.sleep(3000);
System.out.println("库存量" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2021-03-26 13:18:25.023 19481-19481/com.example.myapplication I/System.out: 库存量0
除了AtomicInteger还有AtomicBoolean,AtomicLong。它们分别用于Boolean,Long类型的原子性操作。
Atomic操作类的底层是用了CAS机制。
什么是CAS?Compare And Swap的缩写,翻译过来就是比较并替换。
从思想上来说,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。
CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去尝试更新。
乐观锁适用于线程数比较少的情况,如果是引用类型要注意ABA问题
3.显示锁
public class MainActivity7 extends AppCompatActivity {
private int i = 60000;//共享变量,库存60000
private Lock lock = new ReentrantLock();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main7);
test();
}
public void order() {
lock.lock();//加锁
try {
i--; //可以抛出异常的代码
} finally {
lock.unlock();//解锁
}
}
//模拟高并发的业务场景
public void test() {
try {
for (int j = 0; j < 6; j++) {
new Thread() {
@Override
public void run() {
super.run();
for (int k = 0; k < 10000; k++) {
order();
}
}
}.start();
}
Thread.sleep(3000);
System.out.println("库存量" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2021-03-26 13:29:17.721 19818-19818/com.example.myapplication I/System.out: 库存量0
这种锁比较灵活