为什么这种方法导致并发问题?

时间:2013-06-08 14:56:07

标签: java multithreading

我同步下面的代码,但它会导致并发问题。

我知道这是由多线程引起的,我对synchronized关键字感到困惑。我期望list.length值为100.如何解决?

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ThreadA extends Thread {

    private static byte[] lock = new byte[0];

    private static final List<String> list = new ArrayList<String>();

    @Override
    public void run() {

        System.out.println(list.size());

        synchronized(lock) {
            int size = list.size();
            if( size == 0 ) return;

            if(size >= 100) {
                list.clear();
            }
        }

    }

    public void add(String s) {
        list.add(s);
    }

    public static void main(String[] args) {

        for(int i = 0; i < 100; i++) {
            new ThreadA().start();
            new Thread(new Runnable() {

                @Override
                public void run() {
                    synchronized(lock) {
                        for(int m = 0; m < 100; m++) {
                            list.add(new Date().toLocaleString());
                        }
                    }
                }
            }).start();
        }

        System.out.println("LIST.SIZE:" + list.size());
    }

}

1 个答案:

答案 0 :(得分:2)

两个问题:

  1. println无需同步即可访问list,无需等待线程完成。你会得到那个时刻列表的价值。

  2. 无法保证线程的执行顺序。可能会发生所有ThreadA实例在匿名线程之前运行,结果可能是一个远远超过100的值。