`

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 public class FileLocker { public static void main(String[] args) throws IOException { File f = new File("aaa.txt"); System.out.println(getFileContent...

    java分布式锁实现代码

    本文将深入探讨如何使用Redisson和Curator框架来实现Java环境中的分布式锁。 首先,让我们来看一下Redisson实现的分布式锁。Redis是一个高性能的键值数据库,常被用作分布式系统的缓存或数据存储。Redisson是基于...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    在给定的压缩包文件中,我们关注的是"FastCopyFile.java"、"UseFloatBuffer.java"以及NIO中的文件锁功能。 首先,让我们详细了解一下`FastCopyFile.java`。这个文件很可能是一个示例程序,演示了如何使用Java NIO...

    java实现多线程文件传输

    10. **安全性**:在多线程环境下,文件操作需注意文件锁,避免同一时刻多个线程修改同一文件,造成数据混乱。 通过以上知识点的综合运用,我们可以构建一个高效、安全的多线程文件传输系统。实际编程中,还需要根据...

    java 写文件 java 写文件 java 写文件 java 写文件

    在Java中,写文件是通过`java.io`包中的类实现的,主要涉及File类、FileWriter类、BufferedWriter类等。下面将详细阐述Java写文件的相关知识点。 1. **File类**:File类是文件和目录路径名的抽象表示形式。它不包含...

    java多线程之并发锁

    在 Java 中,还有其他一些锁机制,例如 Semaphore、CountDownLatch 和 CyclicBarrier 等,它们都可以用来实现线程同步和线程安全。 Java 中的多线程编程需要充分考虑线程安全和锁机制的问题,否则可能会导致程序的...

    java文件上传进度条实现基本原理

    通过以上步骤,我们可以实现一个基本的Java文件上传进度条功能。这不仅提高了用户体验,也让文件上传过程变得更加透明。在实际开发中,还需要根据具体需求和环境进行调整和优化,例如,增加上传策略(如限速、优先级...

    java实现windows文件系统操作监控

    6. **文件保护**:为了保护文件,可以设定访问权限或者使用文件锁。Java的`java.nio.file`包提供了丰富的文件操作接口,如`Files.setPosixFilePermissions()`和`Files.newFileChannel()`,可以用来设置权限和创建...

    简单java文件过滤

    当然,实际应用中可能需要考虑更多因素,如错误处理、文件锁、并发访问等。在大型项目中,你可能会选择使用Apache Commons IO库或Java 8的Stream API来简化文件操作。 总的来说,“简单java文件过滤”涉及了Java中...

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

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

    Java Redis分布式锁的正确实现方式详解

    Java Redis分布式锁的正确实现方式详解 Java Redis分布式锁是指使用Redis实现的分布式锁机制,旨在解决分布式系统中的并发问题。分布式锁有三种实现方式:数据库乐观锁、基于Redis的分布式锁和基于ZooKeeper的...

    基于Java向zip压缩包追加文件

    - 为了保证操作的原子性,可以考虑在处理过程中使用文件锁,以防止在压缩过程中文件被其他进程修改。 - 如果ZIP文件非常大,解压和再压缩的过程可能会消耗大量时间和资源,因此在处理大数据量时需要谨慎设计。 6....

    Java版文件系统

    在Java编程环境中,实现一个操作系统级别的文件系统是一项挑战性的工作,因为这涉及到对底层硬件、内存管理和并发控制的理解。然而,通过使用Java提供的类库和API,我们可以构建一个模拟的文件系统,它能够进行基本...

    Java实现文件的多线程下载

    在本案例中,我们将探讨如何使用Java实现文件的多线程下载,这对于处理大文件或者在网络带宽有限的情况下尤其有用。通过多线程下载,可以将文件分割成多个部分并同时下载,从而缩短整体下载时间。 首先,我们需要...

    java 分割文件 将大文件分割成小文件

    例如,如果文件正在被其他进程使用,可能需要实现锁机制。同时,确保在处理文件后正确关闭输入/输出流,以防止资源泄露。 总结起来,Java提供了丰富的API来处理文件操作,包括分割大文件。通过结合`FileInputStream...

    java 加密锁例子

    总结来说,这个Java加密锁例子展示了如何通过JNI调用本地动态库来与坚石公司的ET199加密锁进行通信,以实现软件的保护和授权管理。理解和运用这个示例可以帮助开发者更好地保护他们的软件产品免受非法复制和使用。

    java大文件上传

    这里需要注意文件锁的管理,以防止并发上传时的文件冲突。 对于断点续传,`plupload`会在客户端保存上传进度,如果上传中断,用户可以继续未完成的上传,服务器端需要有相应的机制识别并处理这些续传请求。这通常...

    迅雷下载接口java实现

    在"project"这个压缩包文件中,应该包含该项目的源代码,包括Java的主程序、JNI接口定义以及C++的实现。通过阅读和分析这些代码,你可以更深入地理解如何在Java中利用迅雷的下载能力。记得在实际操作时,要遵循迅雷...

    PersistentIdealHashTree-Java实现

    在Java中,我们可以看到两个关键文件:PersistentIdealHashTreeTest.java和PersistentIdealHashTree.java。前者是测试类,用于验证和测试PersistentIdealHashTree的正确性和性能;后者则是实际的数据结构实现,包含...

Global site tag (gtag.js) - Google Analytics