一、pipe
概念
 pipe 是nio管道2个线程之前的单项数据连接。
 pipe 有2个通道一个是source通道一个是sink通道
数据会写入到source通道从sink通道获取数据。如图:

代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
   | public class PipeTest { public static void main(String[] args) {
  	Pipe pipe = null; 	ExecutorService exec = 	Executors.newFixedThreadPool(2);  try { 	pipe = Pipe.open(); 	final Pipe pipeTemp = pipe; 	exec.submit(new Callable<Object>() { @Override 		public Object call() throws Exception { 		Pipe.SinkChannel sinkChannel = pipeTemp.sink();//向通道中写 	while (true) { 		TimeUnit.SECONDS.sleep(1); 		String newData = "Pipe Test At Time " + 		System.currentTimeMillis(); 		ByteBuffer buf = ByteBuffer.allocate(1024); 		buf.clear(); buf.put(newData.getBytes()); 		buf.flip(); 		while (buf.hasRemaining()) { 	 		System.out.println(buf);  		sinkChannel.write(buf); 	   }     } }  }); 	exec.submit(new Callable<Object>() {  	@Override 	public Object call() throws Exception {Pipe.SourceChannel sourceChannel = pipeTemp.source();//向 	while (true) { 	TimeUnit.SECONDS.sleep(1); 	ByteBuffer buf = ByteBuffer.allocate(1024);  	buf.clear(); 	int bytesRead = sourceChannel.read(buf); 	 	System.out.println("bytesRead=" + bytesRead);  	while (bytesRead > 0) { 	buf.flip(); 	byte b[] = new byte[bytesRead]; int i = 0; 	while (buf.hasRemaining()) { 	b[i] = buf.get(); System.out.printf("%X", b[i]);  	i++;     } 	String s = new String(b);  	System.out.println("=================||" + s);  	bytesRead = sourceChannel.read(buf); } 
  | 
 
二、FileChannel文件锁
  在通道中我们可以对文件或者部分文件进行上锁。上锁和我们了解的线程锁差不多,都是为 了保证数据的一致性。在文件通道 FileChannel 中可以对文件进行上锁,通过 FileLock 可以 对文件进行锁的释放。 文件加锁是建立在文件通道(FileChannel)之上的,套接字通道(SockeChannel)不考虑文 件加锁,因为它是不共享的。
它对文件加锁有两种方式:
- lock
 
- tryLock     
 
两种加锁方式默认都是对整个文件加锁,如果自己配置的话就可以控制加锁的文件范围: position 是加锁的开始位置,size 是加锁长度,shared 是用于控制该锁是共享的还是独占的。 
- lock 是阻塞式的,当有进程对锁进行读取时会等待锁的释放,在此期间它会一直等待;
 
- tryLock 是非阻塞式的,它尝试获得锁,如果这个锁不能获得,那么它会立即返回。
 
release 可以释放锁。
在一个进程中在锁没有释放之前是无法再次获得锁的
在 java 的 NIO 中,通道包下面有一个 FileLock 类,它主要是对文件锁工具的一个描述。在 上一小节中对文件的锁获取其实是 FileChannel 获取的(lock 与 trylock 是 FileChannel 的方 法),它们返回一个 FileLock 对象。
这个类的核心方法有如下这些:
boolean isShared() :判断锁是否为共享类型
abstract boolean isValid() :判断锁是否有效
boolean overlaps():判断此锁定是否与给定的锁定区域重叠 long position():返回文件内锁定区域中第一个字节的位置。
abstract void release() :释放锁
long size() :返回锁定区域的大小,以字节为单位
在文件锁中有 3 种方式可以释放文件锁:
- 锁类释放锁,调用 FileLock 的 release 方法 
 
- 通道类关闭通道,调用 FileChannel 的 close 方法
 
- jvm 虚拟机会在特定情况释放锁。
 
锁类型(独占式和共享式)
我们先区分一下在文件锁中两种锁的区别:
- 独占式的锁就想我们上面测试的那样,只要有一个进程获取了独占锁,那么别的进程只能等待。
 
- 共享锁在一个进程获取的情况下,别的 进程还是可以读取被锁定的文件,但是别的进程不能写只能读。