Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Java concurrency guidelines.pdf
Скачиваний:
16
Добавлен:
23.05.2015
Размер:
1.35 Mб
Скачать

LCK02-J

3.3.5Compliant Solution (Class Name Qualification)

This compliant solution synchronizes using a Base class literal in the parse() and doSomethingAndParse() methods.

class Base {

// ...

public Date parse(String str) throws ParseException { synchronized (Base.class) {

return format.parse(str);

}

}

private class Helper {

public Date doSomethingAndParse(String str) throws ParseException { synchronized(Base.class) { // Synchronizes on Base class literal

// ...

return format.parse(str);

}

}

}

}

Consequently, both Base and Helper lock on Base’s intrinsic lock. Similarly, the Class.forname() method can be used instead of a class literal.

3.3.6Risk Assessment

Synchronizing on the class object returned by getClass() can result in nondeterministic behavior.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

 

 

 

 

 

 

LCK02- J

medium

probable

medium

P8

L2

3.3.7References

[Findbugs 2008]

 

[Miller 2009]

Locking

[Pugh 2008]

“Synchronization”

[Sun 2009b]

 

CMU/SEI-2010-TR-015 | 54

LCK03-J

3.4LCK03-J. Do not synchronize on the intrinsic locks of high-level concurrency objects

It is inappropriate to lock on an object of a class that implements one or both of the following interfaces of the java.util.concurrent.locks package: Lock and Condition. Using the intrinsic locks of these classes is a questionable practice even though the code may appear to function correctly. This problem is commonly discovered when code is refactored from intrinsic locking to the java.util.concurrent dynamic-locking utilities.

3.4.1Noncompliant Code Example (ReentrantLock Lock Object)

The doSomething() method in this noncompliant code example synchronizes on the intrinsic lock of an instance of ReentrantLock instead of the reentrant mutual exclusion Lock encapsulated by ReentrantLock.

private final Lock lock = new ReentrantLock();

public void doSomething() { synchronized(lock) {

// ...

}

}

3.4.2Compliant Solution (lock() and unlock())

Instead of using the intrinsic locks of objects that implement the Lock interface, such as ReentrantLock, use the lock() and unlock() methods provided by the Lock interface.

private final Lock lock = new ReentrantLock();

public void doSomething() { lock.lock();

try {

// ...

}finally { lock.unlock();

}

}

If there is no requirement for using the advanced functionality of the java.util.concurrent package’s dynamic-locking utilities, it is better to use the Executor framework or other concurrency primitives such as synchronization and atomic classes.

CMU/SEI-2010-TR-015 | 55

LCK03-J

3.4.3Risk Assessment

Synchronizing on the intrinsic lock of high-level concurrency utilities can cause nondeterministic behavior because the class can end up with two different locking policies.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

 

 

 

 

 

 

LCK03-J

medium

probable

medium

P8

L2

3.4.4References

[Findbugs 2008]

 

[Miller 2009]

Locking

[Pugh 2008]

“Synchronization”

[Sun 2009b]

 

[Sun 2008a]

Wrapper Implementations

CMU/SEI-2010-TR-015 | 56

LCK04-J

3.5LCK04-J. Do not synchronize on a collection view if the backing collection is accessible

The java.util.Collections interface’s documentation [Sun 2009b] warns about the consequences of failing to synchronize on an accessible collection object when iterating over its view:

It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views. . . Failure to follow this advice may result in non-deterministic behavior.

A class that uses a collection view instead of the backing collection as the lock object may end up with two different locking strategies. In this case, if the backing collection is accessible to multiple threads, the class is not thread-safe.

3.5.1Noncompliant Code Example (Collection View)

This noncompliant code example creates two views: a synchronized view of an empty HashMap encapsulated by the map field and a set view of the map’s keys encapsulated by the set field. This example synchronizes on the set view [Sun 2008a].

// map has package-private accessibility final Map<Integer, String> map =

Collections.synchronizedMap(new HashMap<Integer, String>()); private final Set<Integer> set = map.keySet();

public void doSomething() {

synchronized(set) { // Incorrectly synchronizes on set for (Integer k : set) {

// ...

}

}

}

In this example, HashMap provides the backing collection for Map, which provides the backing collection for Set, as shown in Figure 4:

Figure 4: How Backing Collection Works in the Collection View, Noncompliant Code Example

HashMap is not accessible, but the map view is. Because the set view is synchronized instead of the map view, another thread can modify the contents of map and invalidate the k iterator.

CMU/SEI-2010-TR-015 | 57

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]