[Java] Thread-Safety是什么 – Part 2

阅读时间: 10分钟

接上一篇文章,又来为大家在10分钟内讲解一些有关Thread-safety的介绍。
再讲3个做到Thread-safety的方式。
大家可以因应情况选择一个最合适的表达方法。

4. Synchronized Collections
大家可以轻易地创建一个thread-safe的集合(collection)透过synchronization wrappers。

Collection<Integer> syncCollection = Collections.synchronizedCollection(new ArrayList<>());Thread thread1 = new Thread(() -> syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6)));Thread thread2 = new Thread(() -> syncCollection.addAll(Arrays.asList(7, 8, 9, 10, 11, 12)));thread1.start();thread2.start();

synchronized collections 利用内在锁(intrinsic locking)在每一个method中.
换言之,method在同一时间只可以被一个thread存取,
假如其他threads试图存取,就会被阻挡blocked,直到那个method被上一个thread 解锁(unlocked)。

5. Concurrent Collections
它是synchronized collections的替代品,同样可以做到thread-safe 的集合。
在Java中, 提供了一个java.util.concurrent package,里内有几个concurrent collections 例如: ConcurrentHashMap。

Map<String,String> concurrentMap = new ConcurrentHashMap<>();concurrentMap.put("1", "one");concurrentMap.put("2", "two");concurrentMap.put("3", "three");

不过concurrent collections跟synchronized collections是有不同的地方,concurrent collections 会将数据分成不同部分以做到thread-safety的功能。
在ConcurrentHashMap,每一个thread可以锁住一个map的segment(一个map由不同segments组成)。所以一个map可以同时被多个threads存取。

6. Atomic Objects
可以利用atomic classes来做到thread-safety的功能,Java可以提供AtomicInteger, AtomicLong, AtomicBoolean, 和AtomicReference等元素来完成任务。
首先,Atomic classes可以容许大家完成各种atomic的操作以做到thread-safe,同时没有用到任何synchronization。
会用以下例子详细讲解:

public class Counter {         private int counter = 0;         public void incrementCounter() {        counter += 1;    }         public int getCounter() {        return counter;    }}

假设目前的是一个race condition,两个threads同时存取incrementCounter() method。最后的结果是counter field的值会是2,而当中的incrementCounter()不是atomic。

下面会是一个thread-safe的例子透过利用物件AtomicInteger修改了Counter class:

public class AtomicCounter {         private final AtomicInteger counter = new AtomicInteger();         public void incrementCounter() {        counter.incrementAndGet();    }         public int getCounter() {        return counter.get();    }}

这个例子是thread-safe是因为它在增加数值时利用了atomic的元素- incrementAndGet,先加1再存取加1之后的值。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章