`
qindongliang1922
  • 浏览: 2187875 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117630
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126029
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59984
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71373
社区版块
存档分类
最新评论

来点实用的Java NIO(四)

    博客分类:
  • JAVA
阅读更多
刚刚,在iteye博客里看了一下,散仙的几篇文章好像都挨在一起,不知道这篇文章发了之后,会不会刷屏,实在是不好意思啊。 上班没时间,只能利用下班的时间,留在公司,给大家分享一些有用的技能,也算散仙比较懒吧,散仙实在不愿意晚上回到宿舍之后,再尼玛研究什么技术,我草,那样岂不真的成码农了。


好了,扯淡了几句,下面开始进入正题,本篇散仙要分享的关于NIO里面的文件锁的知识,文件锁的用处,在特定场景下,是非常有用的,那么在开始进行讲解之前,散仙,先借这个知识,来给大家分享一下文件锁在lucene里面发挥的巨大作用。如果想要学习lucene4.x的朋友们,可以参照散仙的博客学习哦。

我们都知道lucene的索引存储,可以放在跟操作系统有关的文件系统里的,而lucene呢,又是决不允许有多个线程同时进行并发写的操作的,那么lucene又不像一些关系型数据库可以采取,锁表,锁行等等一些加锁策略来同步写入操作,那它到底是采用是什么实现的呢?答案毫无疑问,就是采用我们的文件系统加锁策略来实现的,可能用过lucene,solr或es的一些朋友们,有时会发现在我们索引的目录里,莫名其妙的出现了一个以.lock结尾的锁文件,没错,当出现这个文件时,就已经证明你肯定进行过数据的写入操作,
那么可能有些读者还有个疑问,为什么我的锁文件一直都存在啊?我的服务都已经停了呀,它怎么还有呢,我可以不可以把它删除呀?....,别着急,听散仙慢慢的给你介绍下实际情况,大多数时候,我们执行完写入操作后,这个锁文件是会自动删除的,如果它没有自动删除,那么就可能出现如下的几种情况,第一,程序出异常,突然中断了,第二,在写入操作依旧进行的时候我们强制关闭服务了,第三,断电或系统崩溃了。第四,有可能我们写的程序,忘关闭流资源了,造成资源引用依然存在。由以上几种情况,都有可能造成.lock文件没有被lucene自动删除,这时候我们可以手动删除,当然删不删除它,都不影响我们正常使用程序的。你要觉得它留在那里,有损形象,那么你就放心大胆的把它删除吧,当然前提是,不要在有写入操作进行的时候,去删除它。



当然,上面只是散仙分析的一个在lucene中的锁案例,其实这个文件锁,在很多场景都大有用处,因为在某种程度上来说,它可以简洁完美的防止并发。

下面,散仙先给一张,测试用的锁文件目录:

测试,代码如下:
package com.filelock;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;


/***
 * 
 * @author 秦东亮
 * 测试文件锁的功能
 * 
 * **/
public class MyLock {

	public static void main2(String[] args)throws Exception {
		
		File f=new File("D://6//mylock.lock");
		f.delete();
		
	}

	 
	  public static void main(String[] args)throws Exception {
		 // List<String> s=Files.readAllLines(Paths.get("D://6//my.txt"), StandardCharsets.UTF_8);
		  //System.out.println(s.size());
		  //使用FileOutputStream获取channel
		  FileOutputStream f=new FileOutputStream(new File("D://6//mylock.lock"));
		  FileChannel channel=f.getChannel();
		  
		  //非阻塞加锁
		   FileLock lock=channel.tryLock();
		  //阻塞加锁
		  // FileLock lock=channel.lock();
		  if(lock==null){
			  System.out.println("改程序已经被占用.....");
			  System.out.println("阻塞中.....");
			  
		  }else{
			  System.out.println("开始访问.......");
			 Thread.sleep(5000);//5秒后进行访问
			  if(lock!=null){
				  List<String> s=Files.readAllLines(Paths.get("D://6//my.txt"), StandardCharsets.UTF_8);
				  //读取文件,打印内容
				  for(String ss:s){
					  System.out.println(ss);
				  }
				  
				  lock.release();//释放锁
				  lock.close();//关闭资源
				  f.close();//关闭流资源
				  Files.delete(Paths.get("D://6//mylock.lock"));
				  System.out.println("访问完毕删除锁文件");
			  }
		  }
	  
		  
	}
	
	
}

运行时的目录状态,截图如下:

控制台打印效果如下:
开始访问.......
有经验
有关系
有技术
有资本
oh了,你可以去创业了!
访问完毕删除锁文件



最后,我们大家都可以测试一下,让sleep休眠的时间更长一点,然后启动一个程序去访问这个文件,就会报一个异常,该文件已经被占用什么的,现在,我们就可以利用文件锁,来防止写入的并发操作了,至于具体的什么场景,还跟各位大大的业务有关系了。不过在高并发的场景下,建议还是使用一些关系型数据库,或者一些Nosql来解决,做做缓存,负载均衡什么的。总之,一句话,具体场景,具体分析。BOSS们看的都是结果,不会关心你的过程。



好了,今天,散仙就先分享到这里了,感谢各位看官,能够坚持看到最后。





  • 大小: 75.7 KB
  • 大小: 51.5 KB
2
0
分享到:
评论
13 楼 kongxuan 2013-11-28  
qindongliang1922 写道
runshine 写道
qindongliang1922 写道
runshine 写道
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


那位兄弟是对的
你可以看看FileChannel的lock或tryLock方法JDK API文档中描述的最后一句"文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。"
文件锁其实借助的是OS提供的机制,锁的粒度是进程级别的,存在的意义是协调多进程对文件的同时访问.


同一个JVM虚拟机里面,如果有多个线程去并发访问的话,只有先得到锁的线程可以访问,后来的线程,因为锁不能重叠的原因,会抛异常,如果不做处理的话,程序终止运行,所以从某个角度上来说,文件锁也是可以防止同一个JVM里面的线程并发的,可能我们理解的角度不太一样。不过仍然感谢各位朋友,发言交流。


线程的互斥锁是线程的互斥锁,文件锁是文件锁.进程内部做文件的线程级排他访问由程序自身线程同步控制,文件锁是OS提供的行为用来在进程间提供文件排他访问.

你再开个线程进行文件写入就明白了...



我前面说的话,就早已经做过测试了,在这里我们是针对防止并发来说的,并没有去细化到到底是那种锁来实现的,我们理解的角度可能不太一样,感谢,细心发言交流。


我已经无语了。
12 楼 qindongliang1922 2013-11-27  
runshine 写道
qindongliang1922 写道
runshine 写道
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


那位兄弟是对的
你可以看看FileChannel的lock或tryLock方法JDK API文档中描述的最后一句"文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。"
文件锁其实借助的是OS提供的机制,锁的粒度是进程级别的,存在的意义是协调多进程对文件的同时访问.


同一个JVM虚拟机里面,如果有多个线程去并发访问的话,只有先得到锁的线程可以访问,后来的线程,因为锁不能重叠的原因,会抛异常,如果不做处理的话,程序终止运行,所以从某个角度上来说,文件锁也是可以防止同一个JVM里面的线程并发的,可能我们理解的角度不太一样。不过仍然感谢各位朋友,发言交流。


线程的互斥锁是线程的互斥锁,文件锁是文件锁.进程内部做文件的线程级排他访问由程序自身线程同步控制,文件锁是OS提供的行为用来在进程间提供文件排他访问.

你再开个线程进行文件写入就明白了...



我前面说的话,就早已经做过测试了,在这里我们是针对防止并发来说的,并没有去细化到到底是那种锁来实现的,我们理解的角度可能不太一样,感谢,细心发言交流。
11 楼 runshine 2013-11-27  
qindongliang1922 写道
runshine 写道
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


那位兄弟是对的
你可以看看FileChannel的lock或tryLock方法JDK API文档中描述的最后一句"文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。"
文件锁其实借助的是OS提供的机制,锁的粒度是进程级别的,存在的意义是协调多进程对文件的同时访问.


同一个JVM虚拟机里面,如果有多个线程去并发访问的话,只有先得到锁的线程可以访问,后来的线程,因为锁不能重叠的原因,会抛异常,如果不做处理的话,程序终止运行,所以从某个角度上来说,文件锁也是可以防止同一个JVM里面的线程并发的,可能我们理解的角度不太一样。不过仍然感谢各位朋友,发言交流。


线程的互斥锁是线程的互斥锁,文件锁是文件锁.进程内部做文件的线程级排他访问由程序自身线程同步控制,文件锁是OS提供的行为用来在进程间提供文件排他访问.

你再开个线程进行文件写入就明白了...
10 楼 qindongliang1922 2013-11-27  
kongxuan 写道
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


是用来防不同的JVM之间或者JVM和操作系统其他进程之间的锁。


同一个JVM虚拟机里面,如果有多个线程去并发访问的话,只有先得到锁的线程可以访问,后来的线程,因为锁不能重叠的原因,会抛异常,如果不做处理的话,程序终止运行,所以从某个角度上来说,文件锁也是可以防止同一个JVM里面的线程并发的,可能我们理解的角度不太一样。不过仍然感谢各位朋友,发言交流。
9 楼 qindongliang1922 2013-11-27  
runshine 写道
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


那位兄弟是对的
你可以看看FileChannel的lock或tryLock方法JDK API文档中描述的最后一句"文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。"
文件锁其实借助的是OS提供的机制,锁的粒度是进程级别的,存在的意义是协调多进程对文件的同时访问.


同一个JVM虚拟机里面,如果有多个线程去并发访问的话,只有先得到锁的线程可以访问,后来的线程,因为锁不能重叠的原因,会抛异常,如果不做处理的话,程序终止运行,所以从某个角度上来说,文件锁也是可以防止同一个JVM里面的线程并发的,可能我们理解的角度不太一样。不过仍然感谢各位朋友,发言交流。
8 楼 runshine 2013-11-27  
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


那位兄弟是对的
你可以看看FileChannel的lock或tryLock方法JDK API文档中描述的最后一句"文件锁定以整个 Java 虚拟机来保持。但它们不适用于控制同一虚拟机内多个线程对文件的访问。"
文件锁其实借助的是OS提供的机制,锁的粒度是进程级别的,存在的意义是协调多进程对文件的同时访问.
7 楼 kongxuan 2013-11-27  
qindongliang1922 写道
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!


是用来防不同的JVM之间或者JVM和操作系统其他进程之间的锁。
6 楼 qindongliang1922 2013-11-27  
onthewanying 写道
利用中午休息时间一口气把四篇都看了,写的挺好的,提个小建议,使用锁的写法不严谨,应改成 try {} finally{} 写法

嗯,使用try,finally来释放资源,比较安全,散仙出于演示,就没加,正式环境中大家一定要养成良好的习惯!。谢谢指正!
5 楼 onthewanying 2013-11-27  
利用中午休息时间一口气把四篇都看了,写的挺好的,提个小建议,使用锁的写法不严谨,应改成 try {} finally{} 写法
4 楼 qindongliang1922 2013-11-27  
manong_java 写道
不错 学习了。

兄弟什么时候讲讲java.util.concurrent;啊


呵呵,有空一定写几篇,一起学习啊,加油!
3 楼 manong_java 2013-11-27  
不错 学习了。

兄弟什么时候讲讲java.util.concurrent;啊
2 楼 qindongliang1922 2013-11-27  
kongxuan 写道
文件锁是不能防住同一个JVM里面的线程的。

这位兄弟,说话得拿出根据,请举例说明,如果不能防止并发,那这锁存在的意义是什么?还请阁下赐教!
1 楼 kongxuan 2013-11-27  
文件锁是不能防住同一个JVM里面的线程的。

相关推荐

    JavaNIO chm帮助文档

    Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) SocketChannel Java NIO系列教程...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    java NIO.zip

    Java NIO,全称为Non-...总的来说,Java NIO提供了比传统I/O更灵活、更高效的数据传输机制,尤其适用于需要处理大量并发连接的网络应用,如服务器端的开发。通过合理利用NIO的特性,可以构建出高性能、低延迟的系统。

    Java NIO英文高清原版

    总的来说,Java NIO是一个强大的工具,对于需要处理大量并发连接和数据交换的应用来说,它提供了显著的性能提升。Netty则是NIO的一个高级封装,它进一步降低了使用NIO的复杂性,提高了开发效率。学习和理解Java NIO...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    java nio 包读取超大数据文件

    ### Java NIO 处理超大数据文件的知识点详解 #### 一、Java NIO简介 Java NIO(New IO)是Java平台上的新输入/输出流API,它提供了与传统IO(即Java IO)不同的数据处理方式。NIO在Java 1.4版本引入,并在后续版本...

    java NIO技巧及原理

    Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    一个java NIO的例子

    总的来说,Java NIO提供了一种高效、灵活的I/O模型,尤其适合处理高并发的网络应用。这个例子"一个java NIO的例子"是学习和理解Java NIO概念和机制的一个很好的起点。通过分析和运行这个示例,开发者可以更深入地...

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

    Java NIO测试示例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)模式相比,...

    java nio 实现socket

    ### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...

    Java NIO Socket基本

    Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的 Blocking I/O(同步阻塞I/O)相对。NIO在Java 1.4版本引入,其设计目标是提供一种更高效、更灵活的I/O操作方式,特别适合处理大量并发连接...

    java基于NIO实现Reactor模型源码.zip

    java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现Reactor模型源码java基于NIO实现...

    java nio 读文件

    总的来说,Java NIO提供了一种更高效、灵活的方式来处理文件读取和其他I/O操作,尤其适合需要处理大量并发I/O请求的场合,例如服务器端编程。通过熟练掌握NIO,开发者可以构建出更加高效的Java应用程序。

Global site tag (gtag.js) - Google Analytics