一. 先上结论
- 当多个线程共用一个Runnable实现类的对象
numRunnable
时(Thread thread = new Thread(numRunnable,"thread"+i)
),Runnable实现类的成员变量是线程不安全的!
二. 问题复现
public class Test {
public static void main(String[] args) {
int total = insertDataToTN(100,1);
System.out.println("总:"+total);
}
public static int insertDataToTN(int threadCount, final int cycleCount){
class NumRunnable implements Runnable{
int totalSum = 0;
public void run(){
for(int i = 0 ; i<10000;i++){
totalSum++;
}
}
}
NumRunnable numRunnable = new NumRunnable();
List<Thread> threads = new ArrayList<Thread>();
for(int i=0;i<threadCount;i++) {
Thread thread = new Thread(numRunnable,"thread"+i);
thread.start();
threads.add(thread);
}
for(Thread tThread:threads){
try {
tThread.join();
}catch (Exception e){
e.printStackTrace();
}
}
return numRunnable.totalSum;
}
}
三. 解决方法
1. 法1:使用原子类AtomicInteger
public class Test {
public static void main(String[] args) {
AtomicInteger a = insertDataToTN(100,1);
System.out.println(a);
}
public static AtomicInteger insertDataToTN(int threadCount, final int cycleCount){
class NumRunnable implements Runnable{
AtomicInteger totalSum = new AtomicInteger(0);
public void run(){
for(int i = 0 ; i<10000;i++){
totalSum.addAndGet(1);
}
}
}
NumRunnable numRunnable = new NumRunnable();
List<Thread> threads = new ArrayList<Thread>();
for(int i=0;i<threadCount;i++) {
Thread thread = new Thread(numRunnable,"thread"+i);
thread.start();
threads.add(thread);
}
for(Thread tThread:threads){
try {
tThread.join();
}catch (Exception e){
e.printStackTrace();
}
}
return numRunnable.totalSum;
}
}
2. 法2:使用synchronized关键字
public class Test {
public static void main(String[] args) {
int total = insertDataToTN(100,1);
System.out.println("总:"+total);
}
public static int insertDataToTN(int threadCount, final int cycleCount){
class NumRunnable implements Runnable{
int totalSum = 0;
public void run(){
for(int i = 0 ; i<10000;i++){
add();
}
}
public synchronized void add(){
totalSum++;
}
}
NumRunnable numRunnable = new NumRunnable();
List<Thread> threads = new ArrayList<Thread>();
for(int i=0;i<threadCount;i++) {
Thread thread = new Thread(numRunnable,"thread"+i);
thread.start();
threads.add(thread);
}
for(Thread tThread:threads){
try {
tThread.join();
}catch (Exception e){
e.printStackTrace();
}
}
return numRunnable.totalSum;
}
}