锁定所有线程的对象?

时间:2015-11-29 10:46:48

标签: java multithreading synchronized

我有这个小代码示例,在修改列表时,我用synchronized锁定它,但是在读取列表时它会出现ConcurrentModificationException,因为没有“synchronized”,锁定无效。是否可以为使用该对象的所有线程锁定一个对象,甚至是非同步的?

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Test {

    public static void main(String[] args) {

        final Random r = new Random(System.currentTimeMillis());

        List<Integer> list = new ArrayList<>();

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    synchronized (list) {
                        list.add(r.nextInt());
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    for (Integer i : list) {
                        System.out.println(i);
                    }
                }
            }
        }).start();
    }
}

backgorund是我不想改变我的代码中读取对象的所有部分

3 个答案:

答案 0 :(得分:2)

您可以考虑使用List的并发实现,而不是ArrayList。也许是CopyOnWriteArrayList。

final List<Integer> list = new CopyOnWriteArrayList<Integer>();

答案 1 :(得分:1)

  

是否可以锁定使用该对象的所有线程的对象。

总之,不是。当一个线程进入synchronized(foo) {...}块时,这不会阻止其他线程访问或修改foo。它唯一阻止的是,它可以防止其他线程同时在同一个对象上同步。

可以做什么,你是否可以创建自己的类来封装锁和锁保护的数据。

class MyLockedList {
    private final Object lock = new Object();
    private final List<Integer> theList = new ArrayList<>();

    void add(int i) {
        synchronized(lock) {
            theList.add(i);
        }
    }

    void printAll() {
        synchronized(lock) {
            for (Integer i : theList) {
                System.out.println(... i ...);
            }
        }
    }

    ...
}

答案 2 :(得分:0)

如果您可以修改同时使用该对象的功能,只需在每个关键部分添加synchronized

      while (true) {
          synchronized(list){
                for (Integer i : list) {
                      System.out.println(i);
             }
        }
}

如果不能,请创建一个负责锁定线程的指定锁:

Lock lock = new Lock();
new Thread(new Runnable(){
  //...
     synchronized(lock){
       do unsynchonized function on list
     }
  //...
}).start();

new Thread(new Runnable(){
  //...
     synchronized(lock){
       do unsynchonized function on list
     }
  //...
}).start();
如果其中一个函数已经执行某些锁定,后者可能会减慢进程的速度,但这样可以确保始终同步对并发对象的访问。