我将count
多线程代码中发生的exceptions
数量调整为addException
。因此,我所做的是,我创建了一个方法AtomicInteger
,其中我使用addException
计算所有异常。
one is the String
方法接受两个参数boolean flag
,其他参数是catch
,这意味着我们是否因为任何异常而终止程序。意思是,如果该标志为真,那么只要有任何异常,我就需要终止程序。
因此,如果您查看下面的addException
块,我会调用ExecutorService service = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
service.submit(new ReadTask());
}
class ReadTask implements Runnable {
public static ConcurrentHashMap<String, AtomicInteger> exceptionMap = new ConcurrentHashMap<String, AtomicInteger>();
public ReadTask() {
}
@Override
public run() {
try {
.........
} catch (ClassNotFoundException e) {
addException(e.getCause() != null ? e.getCause().toString() : e.toString(), Read.flagTerminate);
LOG.error("Threw a ClassNotFoundException in " + getClass().getSimpleName(), e);
} catch (SQLException e) {
addException(e.getCause() != null ? e.getCause().toString() : e.toString(), Read.flagTerminate);
LOG.error("Threw a SQLException while making connection to database in " + getClass().getSimpleName(), e);
}
}
/**
* A simple method that will add the count of exceptions and name of
* exception to a map
*
* @param cause
* @param flagTerminate
*/
private static void addException(String cause, boolean flagTerminate) {
AtomicInteger count = exceptionMap.get(cause);
if (count == null) {
count = new AtomicInteger();
AtomicInteger curCount = exceptionMap.putIfAbsent(cause, count);
if (curCount != null) {
count = curCount;
}
}
count.incrementAndGet();
if(flagTerminate) {
System.exit(1);
}
}
}
方法来计算异常,并且在方法调用之下我也会记录异常。
addException
问题陈述: -
此代码是否可以进行线程争用?如果是,我如何以更好的方式编写Thread Contention
方法以避免addException
?
此处是否还有高效编写{{1}}方法的方式?
答案 0 :(得分:2)
您的代码看起来在逻辑上是正确的,但仍有可能存在线程争用。
考虑如果每个线程抛出相同的异常会发生什么:他们将序列化更新AtomicInteger
跟踪异常计数。
实际上没有简单的方法:如果所有线程都在更新同一条数据,那么它们几乎必须序列化。那不是问题;那只是现实。
有 方法可以解决这个问题,但它会将一段简单,正确的代码变成复杂的噩梦。
你应该问的问题是“我是否需要才能提高效率?”答案是肯定的,因为例外情况几乎是罕见的。如果上一个问题的答案是肯定的,那么只应询问“如何使其更有效率”的问题。
答案 1 :(得分:0)
//This check-then-act block can cause two threads can see count as null
if (count == null) {
count = new AtomicInteger();
AtomicInteger curCount = exceptionMap.putIfAbsent(cause, count);
if (curCount != null) {
count = curCount;
}
}
建议:
1)Map<Class<?>,AtomicInteger>
如何将Class作为异常的类。
<强>更新强>
尝试使用ThreadLocals
,每个帖子都有自己的地图副本,并会在自己的副本中更新。所以零争用。