传统观点告诉我们,大批量企业Java应用程序应优先使用线程池来生成新的工作线程.使用java.util.concurrent
使这简单明了.
但是,确实存在线程池不适合的情况.我目前正在努力的具体示例是使用InheritableThreadLocal
,它允许ThreadLocal
变量"传递"到任何生成的线程.使用线程池时,此机制会中断,因为工作线程通常不是从请求线程生成的,而是预先存在的.
现在有办法解决这个问题(线程本地可以显式传入),但这并不总是合适或实用.最简单的解决方案是按需生成新的工作线程,然后让它InheritableThreadLocal
完成它的工作.
这让我们回到刚才的问题 - 如果我有一个高容量的网站,在这里用户请求的线程产卵关每个半打工作线程(即不使用线程池),这是怎么回事给JVM的一个问题?我们可能会谈论每秒创建几百个新线程,每个线程持续不到一秒钟.现代JVM是否能很好地优化这一点?我记得在Java中需要对象池的日子,因为对象创建很昂贵.从此变得不必要了.我想知道是否同样适用于线程池.
如果我知道要测量什么,我会对它进行基准测试,但我担心的是问题可能比用剖析器测量的更微妙.
注意:使用线程本地的智慧不是问题所在,所以请不要建议我不要使用它们.
我有一个包含超过7000万行的.csv文件,其中每行生成一个Runnable然后由threadpool执行.这个Runnable会在Mysql中插入一条记录.
更重要的是,我想记录一个用于定位的RandomAccessFile的csv文件的位置.该位置被写入文件.我想在线程池中的所有线程都完成时写入此记录.然后调用ThreadPoolExecutor.shutdown().但是当更多的线路出现时,我又需要一个线程池.如何重用当前的线程池而不是重新创建新的线程池.
代码如下:
public static boolean processPage() throws Exception {
long pos = getPosition();
long start = System.currentTimeMillis();
raf.seek(pos);
if(pos==0)
raf.readLine();
for (int i = 0; i < PAGESIZE; i++) {
String lineStr = raf.readLine();
if (lineStr == null)
return false;
String[] line = lineStr.split(",");
final ExperienceLogDO log = CsvExperienceLog.generateLog(line);
//System.out.println("userId: "+log.getUserId()%512);
pool.execute(new Runnable(){
public void run(){
try {
experienceService.insertExperienceLog(log);
} catch (BaseException e) {
e.printStackTrace();
}
}
});
long end = System.currentTimeMillis();
} …
Run Code Online (Sandbox Code Playgroud) 在Java中,什么时候应该使用静态非最终变量?
例如
private static int MY_VAR = 0;
Run Code Online (Sandbox Code Playgroud)
显然我们不是在谈论常数.
public static final int MY_CONSTANT = 1;
Run Code Online (Sandbox Code Playgroud)
根据我的经验,我经常在使用单身时证明他们是合理的,但后来我最终需要有一个以上的实例并导致自己非常头疼并重新考虑因素.
它们似乎很少应该在实践中使用.你怎么看?