Java中,假设我有一个List,需要用多线程同时处理。怎么办?

Sylow 发布于 2015/10/09 21:01
阅读 3K+
收藏 2

如题。

我现在实现了Callable接口。有一个LinkedList作为属性。

new 10个任务 传递一个LinkedList进去作为属性。然后进程中用 LinkedList removeFirst() 获取LinkedList中得值

for (int i = 1;i < 11; i++) {
			FutureTask<Object> future = new FutureTask<Object>(new Task("线程" + i, taskLinkList)); 
			new Thread(future).start();
}
但是我没有用synchronized  因为用这个同步的话,多线程也会等待,所以没用。

我想请教下这样做会有什么不妥吗?

有没有更好的方法,求指教。谢谢 

以下是问题补充:

@Sylow:我这个List不需要增删改,只需要查询得到就行。 (2015/10/09 21:18)
加载中
1
r
runrunsnail

多线程内,对同一个集合类进行增删改操作时,必须进行同步处理。

有三种方法(LinkedList是非线程安全的集合类):

1、使用线程安全的集合类。(如Vector)它的所有方法都是同步的,几乎不需要自己加同步代码。

2、对于非线程安全的集合类,可以用synchronized自己做同步处理

3、对于非线程安全的集合类,可以使用同步包装方法对集合进行包装,包装后的对象(下例的list)是线程安全的。

   List list = Collections.synchronizedList(new LinkedList(...));

ps:从你给出的代码和说明,貌似你想要在线程内边删除边获取,没看到你有追加的需求。

      如果怕同步的等待时间,为什么不在线程内只获取,不删除,所有线程实行完后,在主线程内一次全部删除呢?

      或者,在主线程里删除获取,只把获取的对象传递给线程,而不是把整个集合给线程。

      线程内具体操作和整体需求不是太明确,只能给出这些提示了。

r
runrunsnail
虽然你没有删除的最终目的,但是你使用removeFirst(删除第一个),就有了删除的动作。所以多线程下,代码有问题,有下面几个方案。 1、不使用removeFirst,传入元素的INDEX,使用get(int index) 。 2、使用线程安全的集合Vector(remove(0))代替LinkedList 3、按现在的代码,必须做同步处理。
1
0x0001
0x0001
这样肯定会出问题的, 前面的人已经说的额不错了, 如果不想用锁,只需要修改Task的构造器,然后代码改成
for (int i = 1;i < 11; i++) {
            FutureTask<Object> future = new FutureTask<Object>(new Task("线程" + i, taskLinkList.get(i-1)); 
            new Thread(future).start();
}

因为是在同一个线程操作linkedlist,所以不会有问题



0
xpbob
xpbob
LinkedList removeFirst() 获取LinkedList中得值,这样线程不安全,就是说二个线程刚获取,第一个线程还没删除的时候,这个任务就被重复操作了,你把你的list用Collections的
synchronizedList
包装成线程安全的list这样就没问题
0
moyiguke
moyiguke

可以用队列么?linkedblockingqueue 这样的。

推荐阅读《Java并发编程实战》

0
Ambitor
Ambitor

java发展到现在synchronized的性能已经得到了很大的提升,所以楼主如果的系统要求不是很高,大可放心使用,或者直接使用jdk 自带线程安全的集合类。

还有现在的去锁设计有很多,比如你可以是只读需求,所以你可以规定每个线程取固定下标的值。当然这也不是最佳方法,只是一种去锁思路而已。

返回顶部
顶部