面试题,是否线程安全?结果是多少?
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);
}
}
这上面使用的是类锁,在所有线程中共用一把锁,所以就可以作到线程安全了。