62//
63if (renameSucceeded) {
64try {
65this.setFile(fileName, false, bufferedIO, bufferSize);
66nextRollover = 0;
67} catch (IOException e) {
68if (e instanceof InterruptedIOException) {
69Thread.currentThread().interrupt();
70}
71LogLog.error("setFile(" + fileName + ", false) call failed.", e);
72}
73}
74 }
75
76 public synchronized void setFile(String fileName, boolean append,
77boolean bufferedIO, int bufferSize) throws IOException {
78super.setFile(fileName, append, this.bufferedIO, this.bufferSize);
79if (append) {
80File f = new File(fileName);
81((CountingQuietWriter) qw).setCount(f.length());
82}
83 }
84 protected void setQWForFiles(Writer writer) {
85this.qw = new CountingQuietWriter(writer, errorHandler);
86 }
87 protected void subAppend(LoggingEvent event) {
88super.subAppend(event);
89if (fileName != null && qw != null) {
90long size = ((CountingQuietWriter) qw).getCount();
91if (size >= maxFileSize && size >= nextRollover) {
92rollOver();
93}
94}
95 }
AsyncAppender类
AsyncAppender顾名思义,就是异步的调用Appender中的doAppend()方法。有多种方法实现这样的功能,比如每当调用doAppend()方法时,doAppend()方法内部启动一个线程来处理这一次调用的逻辑,这个线程可以是新建的线程也可以是线程池,然而我们知道线程是一个比较耗资源的实体,为每一次的操作都创建一个新的线程,而这个线程在这一次调用结束后就不再使用,这种模式是非常不划算的,性能低下;而且即使在这里使用线程池,也会导致在非常多请求同时过来时引起消耗大量的线程池中的线程或者因为线程池已满而阻塞请求。因而这种直接使用线程去处理每一次的请求是不可取的。
另一种常用的方案可以使用生产者和消费中的模式来实现类似的逻辑。即每一次请求做为一个生产者,将请求放到一个Queue中,而由另外一个或多个消费者读取Queue中的内容以处理真正的逻辑。
在最新的Java版本中,我们可以使用BlockingQueue类简单的实现类似的需求,然而由于Log4J的存在远早于BlockingQueue的创建,因而为了实现对以前版本的兼容,它还是自己实现了这样一套生产者消费者模型。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-29497-6.html
不满老天做安排
呵