面試題,是否線程安全?結果是多少?
public class Te {
private static volatile int ii = 0;
public synchronized static void add() {
ii++;
}
private static class Plus implements Runnable {
@Override
public void run() {
while (ii < 10) {
System.out.println(Thread.currentThread().getName() + " - " + ii);
add();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Plus());
threads[i].start();
}
Thread.sleep(1000);
System.out.println("結果:" + ii);
}
}
答案:不是線程安全,上面的只保證了add方法是線程安全,但調用的時候拿到的ii值可能一樣,所以會多加
public class Te {
private static volatile int ii = 0;
public static void add() {
ii++;
}
private static class Plus implements Runnable {
@Override
public void run() {
synchronized (Te.class) {
while (ii < 10) {
System.out.println(Thread.currentThread().getName() + " - " + ii);
add();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Plus());
threads[i].start();
}
Thread.sleep(1000);
System.out.println("結果:" + ii);
}
}
這上面使用的是類鎖,在所有線程中共用一把鎖,所以就可以作到線程安全了。