`

java文件锁的实现

    博客分类:
  • Java
阅读更多

项目使用到集群环境,流程发送时如果确保一个流程不会被两个流程同时调用?

有一种办法是用文件锁的方式来实现。

代码如下:

锁接口:

package lock;

import java.io.FileNotFoundException;
import java.io.IOException;

public interface Lock {

	/**
	 * 检测是否被锁定
	 * @return true被锁定 ,false空闲
	 * */
	public abstract boolean isLocked() throws FileNotFoundException;

	/**
	 * 获取锁资源
	 * @return true成功锁定目标资源 ,false锁定操作失败
	 * */
	public abstract boolean obtain() throws IOException;

	/**
	 * 释放锁
	 * */
	public abstract void unlock();

}
 

 

文件锁的实现:

package lock;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;

public class FileProgrameLock implements Lock{
	private String callerThreadID = null;
	private String lockFileName = null;
	FileChannel channel = null;
	private FileLock lock = null;
	
	public static Lock get(String fileName,String callerThreadID){
		FileProgrameLock d = new FileProgrameLock(fileName);
		d.callerThreadID = callerThreadID;
		return (Lock)d;
	}
	
	public FileProgrameLock(String lockFileName){
		this.lockFileName = lockFileName;
	}
	
	/**
	 * 检测是否被锁定-不建议使用
	 * @return true被锁定 ,false空闲
	 * @deprecated 
	 * */
	public boolean isLocked() throws FileNotFoundException {
		File tf = new File(lockFileName);
		if( ! tf.exists()){
			return false;
		}
		FileChannel __channel = new RandomAccessFile(tf, "rw").getChannel();
		FileLock tl = null;
		try {
			tl = __channel.tryLock();
			if (tl == null) {
				return true;
			} else {
				
				return false;
			}
		} catch (OverlappingFileLockException e) {
			return true;
		} catch (IOException e) {
			return true;
		}catch (Exception e) {
			return true;
		}finally{
			try {
				if(tl != null){
					tl.release();
				}
				tl = null;
				if(__channel.isOpen()){
					__channel.close();
				}
				__channel = null;
				tf = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}

	/**
	 * 获取锁资源
	 * @return true成功锁定目标资源 ,false锁定操作失败
	 * */
	public boolean obtain() throws IOException {
		File tf = new File(lockFileName);
		createFile();
		channel = new RandomAccessFile(tf, "rw").getChannel();
		try {
//			System.out.println("get lock 000 >>>>>>>>>>>>>>>");
			lock = channel.lock();
//			System.out.println("get lock >>>>>>>>>>>>>>>");
			return true;
		} catch (OverlappingFileLockException e) {
			return false;
		}catch (Exception e) {
			return false;
		}
	}

	/**
	 * 释放锁
	 * */
	public void unlock() {
		try {
			if(lock != null){
				lock.release();
			}
			System.out.println(callerThreadID + " unlock XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ");
			if(channel != null && channel.isOpen()){
				channel.close();
			}
			lock = null;
			channel = null;
			this.deleteFile();
		} catch (IOException e) {
		}
	}
	
	protected void finalize() throws Throwable {
		System.out.println(callerThreadID + this.getClass() + " .finalize()");
		super.finalize();
	}
	
	private void createFile() throws IOException{
		try{
			File tf = new File(lockFileName);
			if(! tf.exists()){
				tf.createNewFile();
			}
			tf = null;
		}catch(IOException e){
			System.out.println(e+lockFileName);
			throw e;
		}
	}
	
	private void deleteFile(){
		File tf = new File(lockFileName);
		if(tf.exists()){
			tf.delete();
		}
		tf = null;
	}
}

 

工厂类:

 

package lock;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class MakeLock implements Runnable{
	private String threadID = "";
	public void run() {
		try {
			while(true) {
				test2(threadID);
				Thread.sleep(200);
			}
		} catch (IOException e) {
			System.out.println(e);
			e.printStackTrace();
		} catch (InterruptedException e) {
			System.out.println(e);
		}
	}
	
	public void test2(String threadID) throws FileNotFoundException, IOException, InterruptedException{
		Lock lock = new MakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
			System.out.println(threadID+":obtain...");
			boolean b = lock.obtain();
//当有重叠时会发生等待,所以外侧先执行isLocked()判断
 System.out.println(threadID+":obtained   "+b);
			if(b){//执行业务逻辑
				Thread.sleep(390);
				for(int i = 0 ; i < Integer.MAX_VALUE ; i ++){
					;
				}
				lock.unlock();
			}
		lock = null;
			
	}
	
	public MakeLock(String threadID){
		this.threadID = threadID;
	}
	
	public Lock getLock(String name,String threadID) {
		final StringBuffer buf = new StringBuffer();
		return FileProgrameLock.get(name,threadID);
	}
	
}
 

 

 使用方法:

public void test2(String threadID) throws FileNotFoundException, IOException, InterruptedException{
		Lock lock = new MakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
		if (!lock.isLocked()) {
			System.out.println(threadID+":obtain...");
			boolean b = lock.obtain();
			System.out.println(threadID+":obtained   "+b);
			if(b){//执行业务逻辑
				Thread.sleep(390);
				for(int i = 0 ; i < Integer.MAX_VALUE ; i ++){
					;
				}
				lock.unlock();
			}
		}else{
			System.out.println(threadID+":can't get a lock :"+lock);
		}
		lock = null;
			
	}
 

 

 

多线程调用测试:

 

public static void main(String[] args) {
		//new AAA().test();
		System.out.println("=========================================");
		Thread th1 = new Thread(new MakeLock("==================== thread1 ===================="));
		Thread th2 = new Thread(new MakeLock("#################### thread2 ####################"));
		Thread th3 = new Thread(new MakeLock("@@@@@@@@@@@@@@@@@@@@ thread3 @@@@@@@@@@@@@@@@@@@@"));
		Thread th4 = new Thread(new MakeLock("$$$$$$$$$$$$$$$$$$$$ thread4 $$$$$$$$$$$$$$$$$$$$"));
		Thread th5 = new Thread(new MakeLock("&&&&&&&&&&&&&&&&&&&& thread5 &&&&&&&&&&&&&&&&&&&&"));
		th1.start();
		th2.start();
		th3.start();
		th4.start();
		th5.start();
	}
 

 

=================

经测试可以在共享文件系统下工作。

附件中AAA.java多线程测试代码可以直接运行。

 

 

分享到:
评论

相关推荐

    java 文件锁的简单实现

    主要介绍了java 文件锁的简单实现的相关资料,需要的朋友可以参考下

    Java思维导图xmind文件+导出图片

    Java客户端实现Kafka生产者与消费者实例 kafka的副本机制及选举原理剖析 基于kafka实现应用日志实时上报统计分析 RabbitMQ 初步认识RabbitMQ及高可用集群部署 详解RabbitMQ消息分发机制及主题消息分发 ...

    Java登录时滑动图片解锁

    该文件是使用javaweb相关的知识编写的关于用户登录界面实现滑动图片解锁实现安全登录的功能项目

    基于Java的FastDFS大文件上传与断点续传设计源码

    该项目旨在实现h5与fastdfs之间的高性能断点续传、秒传、大文件上传以及使用redis文件锁。系统提供了文件上传、文件处理、文件存储等功能。通过该项目,开发者可以学习并实践Java技术的应用,为后续的Web开发奠定...

    JAVA_API1.6文档(中文)

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    java 实现的xml文件的读写

    java 实现的xml文件的读写 XML作为全球通用的结构化语言,越来越受人们青睐,各种开发平台(比如Microsoft Studio系列、Oracle系列、Inprise Borland系列等)也都把支持XML开发作为宣传口号之一 。由于笔者所从事的...

    文件夹、文件加密码锁工具

    直接给文件夹的内容加上一个密码锁,可以防止外人访问内容。

    Java 1.6 API 中文 New

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    使用Java单例模式实现一个简单的日志记录器.txt

    这段代码实现了一个简单的日志记录器Logger,其中使用了Java的单例模式。在类的构造方法中,首先定义了一个静态变量instance,用于保存Logger的唯一实例。然后定义了一个静态锁对象lock,用于保证线程安全。接着定义...

    java api最新7.0

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    实现一个拷贝文件的类使用字节流还是字符串.mp4 │ Java面试题13.线程的实现方式 怎么启动线程怎么区分线程.mp4 │ Java面试题14.线程并发库和线程池的作用?.mp4 │ Java面试题15.设计模式和常用的设计模式.mp4 │ ...

    JavaAPI1.6中文chm文档 part1

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    java jdk实列宝典 光盘源代码

    java的声音处理,介绍java中如何处理声音,包括实现响铃,播放wav,au等音频文件,以及控制声音的大小和音量,Beep.java; 媒体播放器,JMFMediaPlayer.java; 12反射 是java程序开发的特征之一,允许java程序对自身...

    Java2实用教程.rar

    10 11文件锁FileLock 10 12Process类中的流 10 13带进度条的输入流 习题 第11章Java网络的基本知识 11 1使用URL 11 2读取URL中的资源 11 3显示URL资源中的HTML文件 11 4处理超链接 11 5InetAdress类 11 6套接字 11 7...

    Java开发详解.zip

    032003_【第20章:Java新IO】_文件锁笔记.pdf 032004_【第20章:Java新IO】_字符集笔记.pdf 032005_【第20章:Java新IO】_Selector笔记.pdf 042101_【课程讲解】_附录:Eclipse开发工具笔记.pdf 050101_〖开发实例〗...

    JavaAPI中文chm文档 part2

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    java jdk-api-1.6 中文 chmd

    java.util.jar 提供读写 JAR (Java ARchive) 文件格式的类,该格式基于具有可选清单文件的标准 ZIP 文件格式。 java.util.logging 提供 JavaTM 2 平台核心日志工具的类和接口。 java.util.prefs 此包允许应用程序...

    深入Java虚拟机(原书第2版).pdf【附光盘内容】

    2.3.7 java平台实现中的bug 2.3.8 测试 2.4 平台无关的七个步骤 2.5 平台无关性的策略 2.6 平台无关性和网络移动对象 2.7 资源页 第3章 安全 3.1 为什么需要安全性 3.2 基本沙箱 3.3 类装载器...

Global site tag (gtag.js) - Google Analytics