调用类的静态方法,不涉及到全局变量时
import java.util.HashMap;
public class SheepThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
Mower.mow();
}
public static void main(String[] args) {
HashMap<Integer,String> map = new HashMap<>();
map.put(0,"喜羊羊");
map.put(1,"懒羊羊");
map.put(2,"沸羊羊");
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new SheepThread());
thread.setName(map.get(i%3)+i);
thread.start();
}
}
}
public class Mower {
public static int i = 0;
public static void mow() {
int sum = 0;
System.out.println("************** 当前线程"+ Thread.currentThread());
for (int i = 0; i < 10; i++) {
System.out.print("小羊收获 " + i + " 斤草. ");
sum += i;
}
if (sum != 45) {
System.out.println("Thread error!");
System.exit(0);
}
System.out.println("************** "+ Thread.currentThread() + "收集了" + sum +"斤青草");
}
}
运行结果
实际执行的结果显示各个线程对静态方法的访问是交叉执行的,但是这并不影响各个线程静态方法中小羊对青草收集总和的统计。
调用类的静态方法,涉及到全局变量时
import java.util.HashMap;
public class SheepThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
// Mower.mow();
try {
Mower.calGrassCake();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
HashMap<Integer,String> map = new HashMap<>();
map.put(0,"喜羊羊");
map.put(1,"懒羊羊");
map.put(2,"沸羊羊");
for (int i = 0; i < 1000; i++) {
Thread thread = new Thread(new SheepThread());
thread.setName(map.get(i%3)+i);
thread.start();
}
Thread.sleep(1000);
System.out.println("************** 慢羊羊统计一共要"+Mower.i+"个青草蛋糕");
}
}
public class Mower {
public static int i = 0;
//统计小羊要吃的青草蛋糕
public static void calGrassCake() throws InterruptedException {
System.out.println(Thread.currentThread() +" 要一个蛋糕");
Thread.sleep(1);
i++;
System.out.println("小计:一共要"+i+"个青草蛋糕");
}
}
运行结果
不正确
修改
对Mower类的calGrassCake()方法加锁
//统计小羊要吃的青草蛋糕
public synchronized static void calGrassCake() throws InterruptedException {
System.out.println(Thread.currentThread() +" 要一个蛋糕");
Thread.sleep(1);
i++;
System.out.println("小计:一共要"+i+"个青草蛋糕");
}
结果
结果正确。
总结
静态方法是否引起线程安全问题主要看该静态方法是否对全局变量(静态变量static member)进行修改操作。