Java BufferedWriter BufferedReader 源码分析

一:BufferedWriter

1、类功能简介:

BufferedWriter、缓存字符输出流、他的功能是为传入的底层字符输出流提供缓存功能、同样当使用底层字符输出流向目的地中写入字符或者字符数组时、每写入一次就要打开一次到目的地的连接、这样频繁的访问不断效率底下、也有可能会对存储介质造成一定的破坏、比如当我们向磁盘中不断的写入字节时、夸张一点、将一个非常大单位是G的字节数据写入到磁盘的指定文件中的、没写入一个字节就要打开一次到这个磁盘的通道、这个结果无疑是恐怖的、而当我们使用BufferedWriter将底层字符输出流、比如FileReader包装一下之后、我们可以在程序中先将要写入到文件中的字符写入到BufferedWriter的内置缓存空间中、然后当达到一定数量时、一次性写入FileReader流中、此时、FileReader就可以打开一次通道、将这个数据块写入到文件中、这样做虽然不可能达到一次访问就将所有数据写入磁盘中的效果、但也大大提高了效率和减少了磁盘的访问量!这就是其意义所在、 他的具体工作原理在这里简单提一下:这里可能说的比较乱、具体可以看源码、不懂再回头看看这里、当程序中每次将字符或者字符数组写入到BufferedWriter中时、都会检查BufferedWriter中的缓存字符数组buf(buf的大小是默认的或者在创建bw时指定的、一般使用默认的就好)是否存满、如果没有存满则将字符写入到buf中、如果存满、则调用底层的writer(char[] b, int off, int len)将buf中的所有字符一次性写入到底层out中、如果写入的是字符数组、如果buf中已满则同上面满的时候的处理、如果能够存下写入的字符数组、则存入buf中、如果存不下、并且要写入buf的字符个数小于buf的长度、则将buf中所有字符写入到out中、然后将要写入的字符存放到buf中(从下标0开始存放)、如果要写入out中的字符超过buf的长度、则直接写入out中、

2、BufferedWriter  API简介:

    A:关键字
  private Writer out;		 底层字符输出流

  private char cb[];		 缓冲数组

  private int nChars, nextChar;		 nChars--cb的size,nextChar--cb中下一个字符的下标

  private static int defaultCharBufferSize = 8192;		 默认cb大小

  private String lineSeparator;		换行符、用于newLine方法。不同平台具有不同的值。

    B:构造方法

  BufferedWriter(Writer out)		使用默认cb大小创建BufferedWriter bw。

  BufferedWriter(Writer out, int sz)		使用默认cb大小创建BufferedWriter bw。

    C:一般方法

  void close()		关闭此流、释放与此流有关的资源。

  void flushBuffer()		将cb中缓存的字符flush到底层out中、

  void flush()	刷新此流、同时刷新底层out流

  void newLine()		写入一个换行符。

  void write(int c)		将一个单个字符写入到cb中。

  void write(char cbuf[], int off, int len)	将一个从下标off开始长度为len个字符写入cb中

  void write(String s, int off, int len)		将一个字符串的一部分写入cb中

3、源码分析

package com.chy.io.original.code;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * 为字符输出流提供缓冲功能、提高效率。可以使用指定字符缓冲数组大小也可以使用默认字符缓冲数组大小。
 */

public class BufferedWriter extends Writer {

	//底层字符输出流
  private Writer out;

  //缓冲数组
  private char cb[];
  //nChars--cb中总的字符数,nextChar--cb中下一个字符的下标
  private int nChars, nextChar;

  //默认cb大小
  private static int defaultCharBufferSize = 8192;

  /**
   * Line separator string. This is the value of the line.separator
   * property at the moment that the stream was created.
   * 换行符、用于newLine方法。不同平台具有不同的值。
   */
  private String lineSeparator;

  /**
   * 使用默认cb大小创建BufferedWriter bw。
   */
  public BufferedWriter(Writer out) {
  	this(out, defaultCharBufferSize);
  }

  /**
   * 使用指定cb大小创建br、初始化相关字段
   */
  public BufferedWriter(Writer out, int sz) {
		super(out);
			if (sz <= 0)
			  throw new IllegalArgumentException("Buffer size <= 0");
			this.out = out;
			cb = new char[sz];
			nChars = sz;
			nextChar = 0;
			//获取不同平台下的换行符表示方式。
			lineSeparator =	(String) java.security.AccessController.doPrivileged(
		        new sun.security.action.GetPropertyAction("line.separator"));
  }

  /** 检测底层字符输出流是否关闭*/
  private void ensureOpen() throws IOException {
		if (out == null)
		  throw new IOException("Stream closed");
  }

  /**
   * 将cb中缓存的字符flush到底层out中、但是不flush底层out中的字符。
   * 并且将cb清空。
   */
  void flushBuffer() throws IOException {
		synchronized (lock) {
		  ensureOpen();
		  if (nextChar == 0)
		  	return;
		  out.write(cb, 0, nextChar);
		  nextChar = 0;
		}
  }

  /**
   * 将一个单个字符写入到cb中。
   */
  public void write(int c) throws IOException {
		synchronized (lock) {
		  ensureOpen();
		  if (nextChar >= nChars)
			flushBuffer();
		  cb[nextChar++] = (char) c;
		}
  }

  /**
   * Our own little min method, to avoid loading java.lang.Math if we've run
   * out of file descriptors and we're trying to print a stack trace.
   */
  private int min(int a, int b) {
	if (a < b) return a;
	return b;
  }

  /**
   * 将一个从下标off开始长度为len个字符写入cb中
   */
  public void write(char cbuf[], int off, int len) throws IOException {
		synchronized (lock) {
		  ensureOpen();
	      if ((off < 0) || (off > cbuf.length) || (len < 0) ||
	        ((off + len) > cbuf.length) || ((off + len) < 0)) {
	        throw new IndexOutOfBoundsException();
	      } else if (len == 0) {
	        return;
	      } 

		  if (len >= nChars) {
				/* 如果len大于cb的长度、那么就直接将cb中现有的字符和cbuf中的字符写入out中、
				 * 而不是写入cb、再写入out中 。
				 */
				flushBuffer();
				out.write(cbuf, off, len);
				return;
		  }

		  int b = off, t = off + len;
		  while (b < t) {
				int d = min(nChars - nextChar, t - b);
				System.arraycopy(cbuf, b, cb, nextChar, d);
				b += d;
				nextChar += d;
				if (nextChar >= nChars)
				  flushBuffer();
		  }
		}
  }

  /**
   * 将一个字符串的一部分写入cb中
   */
  public void write(String s, int off, int len) throws IOException {
	synchronized (lock) {
	  ensureOpen();

	  int b = off, t = off + len;
	  while (b < t) {
		int d = min(nChars - nextChar, t - b);
		s.getChars(b, b + d, cb, nextChar);
		b += d;
		nextChar += d;
		if (nextChar >= nChars)
		  flushBuffer();
	  }
	}
  }

  /**
   * 写入一个换行符。
   */
  public void newLine() throws IOException {
  	write(lineSeparator);
  }

  /**
   * 刷新此流、同时刷新底层out流
   */
  public void flush() throws IOException {
		synchronized (lock) {
		  flushBuffer();
		  out.flush();
		}
  }
  /**
   * 关闭此流、释放与此流有关的资源。
   */
  public void close() throws IOException {
		synchronized (lock) {
		  if (out == null) {
			return;
		  }
		  try {
		    flushBuffer();
		  } finally {
		    out.close();
		    out = null;
		    cb = null;
		  }
		}
  }
}

4、实例演示:与下面的BufferedReader结合使用实现字符类型的文件的拷贝。

二:BufferedReader

1、类功能简介:

缓冲字符输入流、他的功能是为传入的底层字符输入流提供缓冲功能、他会通过底层字符输入流(in)中的字符读取到自己的buffer中(内置缓存字符数组)、然后程序调用BufferedReader的read方法将buffer中的字符读取到程序中、当buffer中的字符被读取完之后、BufferedReader会从in中读取下一个数据块到buffer中供程序读取、直到in中数据被读取完毕、这样做的好处一是提高了读取的效率、二是减少了打开存储介质的连接次数、详细的原因下面BufferedWriter有说到。其有个关键的方法fill()就是每当buffer中数据被读取完之后从in中将数据填充到buffer中、程序从内存中读取数据的速度是从磁盘中读取的十倍!这是一个很恐怖的效率的提升、同时我们也不能无禁止的指定BufferedReader的buffer大小、毕竟、一次性读取in中耗时较长、二是内存价格相对昂贵、我们能做的就是尽量在其中找到合理点。一般也不用我们费这个心、创建BufferedReader时使用buffer的默认大小就好。

2、BufferedReader  API简介:

 A:构造方法

  BufferedReader(Reader in, int sz)		根据指定大小和底层字符输入流创建BufferedReader。br

  BufferedReader(Reader in)		使用默认大小创建底层输出流的缓冲流

    B:一般方法

  void close()	关闭此流、释放与此流有关的所有资源

  void mark(int readAheadLimit)	标记此流此时的位置

  boolean markSupported()		判断此流是否支持标记

  void reset()	重置in被最后一次mark的位置

  boolean ready()		判断此流是否可以读取字符

  int read()		读取单个字符、以整数形式返回。如果读到in的结尾则返回-1。

  int read(char[] cbuf, int off, int len)	将in中len个字符读取到cbuf从下标off开始长度len中

  String readLine()	读取一行

  long skip(long n)		丢弃in中n个字符

 3、源码分析

package com.chy.io.original.code;

import java.io.IOException;

/**
 * 为底层字符输入流添加字符缓冲cb数组。提高效率
 * @version 	1.1, 13/11/17
 * @author		andyChen
 */

public class BufferedReader extends Reader {

  private Reader in; 

  private char cb[];
  private int nChars, nextChar;

  private static final int INVALIDATED = -2;
  private static final int UNMARKED = -1;
  private int markedChar = UNMARKED;
  private int readAheadLimit = 0; /* Valid only when markedChar > 0 */

  /** If the next character is a line feed, skip it */
  private boolean skipLF = false;

  /** The skipLF flag when the mark was set */
  private boolean markedSkipLF = false;

  private static int defaultCharBufferSize = 8192;
  private static int defaultExpectedLineLength = 80;

  /**
   * 根据指定大小和底层字符输入流创建BufferedReader。br
   */
  public BufferedReader(Reader in, int sz) {
		super(in);
		if (sz <= 0)
		  throw new IllegalArgumentException("Buffer size <= 0");
		this.in = in;
		cb = new char[sz];
		nextChar = nChars = 0;
  }

  /**
   * 使用默认大小创建底层输出流的缓冲流
   */
  public BufferedReader(Reader in) {
  	this(in, defaultCharBufferSize);
  }

  /** 检测底层字符输入流in是否关闭 */
  private void ensureOpen() throws IOException {
		if (in == null)
		  throw new IOException("Stream closed");
  }

  /**
   * 填充cb。
   */
  private void fill() throws IOException {
		int dst;
		if (markedChar <= UNMARKED) {
		  /* No mark */
		  dst = 0;
		} else {
		  /* Marked */
		  int delta = nextChar - markedChar;
		  if (delta >= readAheadLimit) {
			/* Gone past read-ahead limit: Invalidate mark */
			markedChar = INVALIDATED;
			readAheadLimit = 0;
			dst = 0;
		  } else {
			if (readAheadLimit <= cb.length) {
			  /* Shuffle in the current buffer */
			  System.arraycopy(cb, markedChar, cb, 0, delta);
			  markedChar = 0;
			  dst = delta;
			} else {
			  /* Reallocate buffer to accommodate read-ahead limit */
			  char ncb[] = new char[readAheadLimit];
			  System.arraycopy(cb, markedChar, ncb, 0, delta);
			  cb = ncb;
			  markedChar = 0;
			  dst = delta;
			}
	        nextChar = nChars = delta;
		  }
		}

		int n;
		do {
		  n = in.read(cb, dst, cb.length - dst);
		} while (n == 0);
		if (n > 0) {
		  nChars = dst + n;
		  nextChar = dst;
		}
  }

  /**
   * 读取单个字符、以整数形式返回。如果读到in的结尾则返回-1。
   */
  public int read() throws IOException {
		synchronized (lock) {
		  ensureOpen();
		  for (;;) {
			if (nextChar >= nChars) {
			  fill();
			  if (nextChar >= nChars)
				return -1;
			}
			if (skipLF) {
			  skipLF = false;
			  if (cb[nextChar] == '\n') {
				nextChar++;
				continue;
			  }
			}
			return cb[nextChar++];
		  }
		}
  }

  /**
   * 将in中len个字符读取到cbuf从下标off开始长度len中
   */
  private int read1(char[] cbuf, int off, int len) throws IOException {
		if (nextChar >= nChars) {
		  /* If the requested length is at least as large as the buffer, and
		    if there is no mark/reset activity, and if line feeds are not
		    being skipped, do not bother to copy the characters into the
		    local buffer. In this way buffered streams will cascade
		    harmlessly. */
		  if (len >= cb.length && markedChar <= UNMARKED && !skipLF) {
			return in.read(cbuf, off, len);
		  }
		  fill();
		}
		if (nextChar >= nChars) return -1;
		if (skipLF) {
		  skipLF = false;
		  if (cb[nextChar] == '\n') {
			nextChar++;
			if (nextChar >= nChars)
			  fill();
			if (nextChar >= nChars)
			  return -1;
		  }
		}
		int n = Math.min(len, nChars - nextChar);
		System.arraycopy(cb, nextChar, cbuf, off, n);
		nextChar += n;
		return n;
  }

  /**
   * 将in中len个字符读取到cbuf从下标off开始长度len中
   */
  public int read(char cbuf[], int off, int len) throws IOException {
    synchronized (lock) {
	  ensureOpen();
      if ((off < 0) || (off > cbuf.length) || (len < 0) ||
        ((off + len) > cbuf.length) || ((off + len) < 0)) {
        throw new IndexOutOfBoundsException();
      } else if (len == 0) {
        return 0;
      }

	  int n = read1(cbuf, off, len);
	  if (n <= 0) return n;
	  while ((n < len) && in.ready()) {
		int n1 = read1(cbuf, off + n, len - n);
		if (n1 <= 0) break;
		n += n1;
	  }
	  return n;
	}
  }

  /**
   * 从in中读取一行、是否忽略换行符
   */
  String readLine(boolean ignoreLF) throws IOException {
		StringBuffer s = null;
		int startChar;

    synchronized (lock) {
      ensureOpen();
	  boolean omitLF = ignoreLF || skipLF;
		bufferLoop:
		for (;;) {

			if (nextChar >= nChars)
			  fill();
			if (nextChar >= nChars) { /* EOF */
			  if (s != null && s.length() > 0)
				return s.toString();
			  else
				return null;
			}
			boolean eol = false;
			char c = 0;
			int i;

	        /* Skip a leftover '\n', if necessary */
			if (omitLF && (cb[nextChar] == '\n'))
	          nextChar++;
			skipLF = false;
			omitLF = false;

		  charLoop:
			for (i = nextChar; i < nChars; i++) {
			  c = cb[i];
			  if ((c == '\n') || (c == '\r')) {
				eol = true;
				break charLoop;
			  }
			}

			startChar = nextChar;
			nextChar = i;

			if (eol) {
			  String str;
			  if (s == null) {
				str = new String(cb, startChar, i - startChar);
			  } else {
				s.append(cb, startChar, i - startChar);
				str = s.toString();
			  }
			  nextChar++;
			  if (c == '\r') {
				skipLF = true;
			  }
			  return str;
			}

			if (s == null)
			  s = new StringBuffer(defaultExpectedLineLength);
			s.append(cb, startChar, i - startChar);
		  }
    }
  }

  /**
   * 从in中读取一行、
   */
  public String readLine() throws IOException {
    return readLine(false);
  }

  /**
   * 丢弃in中n个字符
   */
  public long skip(long n) throws IOException {
		if (n < 0L) {
		  throw new IllegalArgumentException("skip value is negative");
		}
		synchronized (lock) {
		  ensureOpen();
		  long r = n;
		  while (r > 0) {
			if (nextChar >= nChars)
			  fill();
			if (nextChar >= nChars)	/* EOF */
			  break;
			if (skipLF) {
			  skipLF = false;
			  if (cb[nextChar] == '\n') {
				nextChar++;
			  }
			}
			long d = nChars - nextChar;
			if (r <= d) {
			  nextChar += r;
			  r = 0;
			  break;
			}
			else {
			  r -= d;
			  nextChar = nChars;
			}
		  }
		  return n - r;
		}
  }

  /**
   * 判断cb中是否为空、或者底层in中是否有可读字符。
   */
  public boolean ready() throws IOException {
		synchronized (lock) {
		  ensureOpen();

		  /*
		   * If newline needs to be skipped and the next char to be read
		   * is a newline character, then just skip it right away.
		   */
		  if (skipLF) {
			/* Note that in.ready() will return true if and only if the next
			 * read on the stream will not block.
			 */
			if (nextChar >= nChars && in.ready()) {
			  fill();
			}
			if (nextChar < nChars) {
			  if (cb[nextChar] == '\n')
				nextChar++;
			  skipLF = false;
			}
		  }
		  return (nextChar < nChars) || in.ready();
		}
  }

  /**
   * 判断此流是否支持标记
   */
  public boolean markSupported() {
  	return true;
  }

  /**
   * 标记此流此时的位置、当调用reset方法失效前最多允许读取readAheadLimit个字符。
   */
  public void mark(int readAheadLimit) throws IOException {
		if (readAheadLimit < 0) {
		  throw new IllegalArgumentException("Read-ahead limit < 0");
		}
		synchronized (lock) {
		  ensureOpen();
		  this.readAheadLimit = readAheadLimit;
		  markedChar = nextChar;
		  markedSkipLF = skipLF;
		}
  }

  /**
   * 重置in被最后一次mark的位置。即下一个字符从被最后一次mark的位置开始读取。
   */
  public void reset() throws IOException {
		synchronized (lock) {
		  ensureOpen();
		  if (markedChar < 0)
			throw new IOException((markedChar == INVALIDATED)
					   ? "Mark invalid"
					   : "Stream not marked");
		  nextChar = markedChar;
		  skipLF = markedSkipLF;
		}
  }

  //关闭此流、释放与此流有关的所有资源
  public void close() throws IOException {
		synchronized (lock) {
		  if (in == null)
			return;
		  in.close();
		  in = null;
		  cb = null;
		}
  }
}

4、实例演示:

package com.chy.io.original.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class BufferedWriterAndBufferedReaderTest {
	/**
	 * 这里对这两个类的测试比较简单、就是对文件字符流进行包装、实现文件拷贝
	 * 有兴趣的可以测试一下效率、、偷个懒、、可无视
	 */
	public static void main(String[] args) throws IOException{
		File resouceFile = new File("D:\\test.txt");
		File targetFile = new File("E:\\copyOftest.txt");

		BufferedReader br = new BufferedReader(new FileReader(resouceFile));
		BufferedWriter bw = new BufferedWriter(new FileWriter(targetFile));

		char[] cbuf = new char[1024];
		int n = 0;
		while((n = br.read(cbuf)) != -1){
			bw.write(cbuf, 0, n);
		}
		//不要忘记刷新和关闭流、否则一方面资源没有及时释放、另一方面有可能照成数据丢失
		br.close();
		bw.flush();
		bw.close();
	}
}

总结:

对于BufferedReader、BufferedWriter、本质就是为底层字符输入输出流添加缓冲功能、先将底层流中的要读取或者要写入的数据先以一次读取一组的形式来讲数据读取或者写入到buffer中、再对buffer进行操作、这样不但效率、还能节省资源。最后、在程序中、出于效率的考虑、也应为低级流使用这两个类进行装饰一下、而不是直接拿着流直接上、觉得能实现就行。

(0)

相关推荐

  • Java中BufferedReader与BufferedWriter类的使用示例

    BufferedReader BufferedReader 是缓冲字符输入流.它继承于Reader. BufferedReader 的作用是为其他字符输入流添加一些缓冲功能. 创建BufferReader时,我们会通过它的构造函数指定某个Reader为参数.BufferReader会将该Reader中的数据分批读取,每次读取一部分到缓冲中:操作完缓冲中的这部分数据之后,再从Reader中读取下一部分的数据. 为什么需要缓冲呢?原因很简单,效率问题!缓冲中的数据实际上是保存在内存中,而原始数据可能

  • Java 中的 BufferedWriter 介绍_动力节点Java学院整理

    BufferedWriter 介绍 BufferedWriter 是缓冲字符输出流.它继承于Writer. BufferedWriter 的作用是为其他字符输出流添加一些缓冲功能. BufferedWriter 函数列表  // 构造函数 BufferedWriter(Writer out) BufferedWriter(Writer out, int sz) void close() // 关闭此流,但要先刷新它. void flush() // 刷新该流的缓冲. void newLine()

  • Java BufferedWriter BufferedReader 源码分析

    一:BufferedWriter 1.类功能简介: BufferedWriter.缓存字符输出流.他的功能是为传入的底层字符输出流提供缓存功能.同样当使用底层字符输出流向目的地中写入字符或者字符数组时.每写入一次就要打开一次到目的地的连接.这样频繁的访问不断效率底下.也有可能会对存储介质造成一定的破坏.比如当我们向磁盘中不断的写入字节时.夸张一点.将一个非常大单位是G的字节数据写入到磁盘的指定文件中的.没写入一个字节就要打开一次到这个磁盘的通道.这个结果无疑是恐怖的.而当我们使用Buffered

  • Java集合框架源码分析之LinkedHashMap详解

    LinkedHashMap简介 LinkedHashMap是HashMap的子类,与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表,因此它保留了节点插入的顺序,可以使节点的输出顺序与输入顺序相同. LinkedHashMap可以用来实现LRU算法(这会在下面的源码中进行分析). LinkedHashMap同样是非线程安全的,只在单线程环境下使用. LinkedHashMap源码剖析 LinkedHashM

  • Java 读写锁源码分析

    前言 在实际项目中,比如我们有一个共享资源文件,我们程序会会同时并发的去读.写这个共享资源文件,那怎么能保证在高并发场景下安全.高效读写呢?OK,看了下文便知 提示:以下是本篇文章正文内容,案例仅供参考 一.技术介绍 1.ReentranReadWriteLock是什么? ReadWriteLock提供了readLock和writeLock两种锁的操作机制,一个是读锁,一个是写锁,而它的实现类就是ReentranReadWriteLock 读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的

  • Java struts2请求源码分析案例详解

    Struts2是Struts社区和WebWork社区的共同成果,我们甚至可以说,Struts2是WebWork的升级版,他采用的正是WebWork的核心,所以,Struts2并不是一个不成熟的产品,相反,构建在WebWork基础之上的Struts2是一个运行稳定.性能优异.设计成熟的WEB框架. 我这里的struts2源码是从官网下载的一个最新的struts-2.3.15.1-src.zip,将其解压即可.里面的目录页文件非常的多,我们只需要定位到struts-2.3.15.1\src\core

  • Java Array.sort()源码分析讲解

    阅读起点: Arrays.sort(nums1); 使用ctrl+左键进入sort()方法 1.Arrays.sort() 关于sort()的方法一共有14个,就目前调用的来看是以下这种最基础的. public static void sort(int[] a) { DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); } 2.DualPivotQuicksort DualPivotQuicksort即双轴快排,定义了七种原始类型的排序

  • Java并发LinkedBlockingQueue源码分析

    目录 简介 常量 构造方法 put await isOnSyncQueue signal 简介 LinkedBlockingQueue是一个阻塞的有界队列,底层是通过一个个的Node节点形成的链表实现的,链表队列中的头节点是一个空的Node节点,在多线程下操作时会使用ReentrantLock锁来保证数据的安全性,并使用ReentrantLock下的Condition对象来阻塞以及唤醒线程. 常量 /** * 链表中的节点类 */ static class Node<E> { //节点中的元素

  • Java并发 结合源码分析AQS原理

    前言: 如果说J.U.C包下的核心是什么?那我想答案只有一个就是AQS.那么AQS是什么呢?接下来让我们一起揭开AQS的神秘面纱 AQS是什么? AQS是AbstractQueuedSynchronizer的简称.为什么说它是核心呢?是因为它提供了一个基于FIFO的队列和state变量来构建锁和其他同步装置的基础框架.下面是其底层的数据结构. AQS的特点 1.其内使用Node实现FIFO(FirstInFirstOut)队列.可用于构建锁或者其他同步装置的基础框架 2.且利用了一个int类表示

  • Java并发Timer源码分析

    timer在JDK里面,是很早的一个API了.具有延时的,并具有周期性的任务,在newScheduledThreadPool出来之前我们一般会用Timer和TimerTask来做,但是Timer存在一些缺陷,为什么这么说呢? Timer只创建唯一的线程来执行所有Timer任务.如果一个timer任务的执行很耗时,会导致其他TimerTask的时效准确性出问题.例如一个TimerTask每10秒执行一次,而另外一个TimerTask每40ms执行一次,重复出现的任务会在后来的任务完成后快速连续的被

  • java.util.Collection源码分析与深度理解

    写在开头 java.util.Collection 作为Java开发最常用的接口之一,我们经常使用,今天我带大家一起研究一下Collection接口,希望对大家以后的编程以及系统设计能有所帮助,本文所研究的jdk版本为jdk1.8.0_131 明确一下几点: Collection是接口,其继承了Iterable接口 Collection属于单值类型集合,重点子接口List接口和Set接口 Java.util.List接口(有序.不唯一) ArraryList ArrayList 是一个数组队列,

  • Java集合系列之LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHashMap源码之前,读者有必要先去了解HashMap的源码,可以查看我上一篇文章的介绍<Java集合系列[3]----HashMap源码分析>.只要深入理解了HashMap的实现原理,回过头来再去看LinkedHashMap,HashSet和LinkedHashSet的源码那都是非常简单的.因此,读

随机推荐