前言:
实际开发中光听说多线程问题,多线程问题,到底啥是多线程问题?
解释:
多线程问题是指:多个线程(2个及以上)在长循环中同时操作同一个变量(可延伸为内存空间),会导致变量错乱问题(可能不是我们想要的结果)
mThread.join();等待线程执行完毕
final int[] num = new int[1];
Thread mThread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
num[0]++;
}
System.out.println("+num[0]: " + num[0]);
}
};
Thread mThread1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
num[0]--;
}
System.out.println("-num[0]: " + num[0]);
}
};
mThread.start();
mThread1.start();
try {
mThread.join();
mThread1.join();
} catch (InterruptedException mE) {
mE.printStackTrace();
}
System.out.println("final num[0]: " + num[0]);
现象:
循环次数是1000,最终结果是0;当是10000时,最终结果不再是0
2021-03-23 16:42:10.179 6240-6256/com.wintec.myapplication I/System.out: +num[0]: 1000
2021-03-23 16:42:10.179 6240-6257/com.wintec.myapplication I/System.out: -num[0]: 0
2021-03-23 16:42:10.179 6240-6240/com.wintec.myapplication I/System.out: final num[0]: 0
10000次日志
2021-03-23 17:02:15.589 6419-6435/com.wintec.myapplication I/System.out: +num[0]: -5112
2021-03-23 17:02:15.589 6419-6436/com.wintec.myapplication I/System.out: -num[0]: -5323
2021-03-23 17:02:15.589 6419-6419/com.wintec.myapplication I/System.out: final num[0]: -5323
此时,便是多线程问题
怎么解决?
使用syncronized关键字给容易出现线程切换的地方加锁[修改共享变量的线程代码块]
num[0]++;实际jvm是进行了3次操作,ILOAD IADD ISTORE,容易出现线程切换
final int[] num = new int[1];
Thread mThread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
synchronized (UserLoginActivity.this){
num[0]++;
}
}
System.out.println("+num[0]: " + num[0]);
}
};
Thread mThread1 = new Thread() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
synchronized (UserLoginActivity.this){
num[0]--;
}
}
System.out.println("-num[0]: " + num[0]);
}
};
mThread.start();
mThread1.start();
try {
mThread.join();
mThread1.join();
} catch (InterruptedException mE) {
mE.printStackTrace();
}
System.out.println("final num[0]: " + num[0]);
2021-03-23 17:17:35.654 7008-7027/com.wintec.myapplication I/System.out: -num[0]: -11
2021-03-23 17:17:35.655 7008-7026/com.wintec.myapplication I/System.out: +num[0]: 0
2021-03-23 17:17:35.657 7008-7008/com.wintec.myapplication I/System.out: final num[0]: 0