众所周知,Java中锁的概念是非常重要的,锁可以保证资源的安全可控,恰当使用锁即可使得资源高效利用,又能保证线程的安全访问,编程中在读取文件的时候常常碰到文件锁的使用,本文简单阐述文件锁在Java中的使用范例,代码仅供参考。
FileLock文件锁
public abstract class FileLock implements AutoCloseable {……}
“Locks are associated with files, not channels. Use locks to coordinate with external processes, not between threads in the same JVM.”
public static String readChannel(final File file, final String encoding) { final StringBuilder builder = new StringBuilder(); FileLock fileLock = null; // FileInputStream will throws java.nio.channels.NonWritableChannelException try(RandomAccessFile ra = new RandomAccessFile(file, "rw"); FileChannel fileChannel = ra.getChannel()) { do { fileLock = fileChannel.tryLock(); } while (null == lock); ByteBuffer buffer = ByteBuffer.allocate(1024); while ((fileChannel.read(buffer)) != -1) { buffer.flip(); // Flip buffer builder.append(Charset.forName(setCharset(encoding)).decode(buffer)); buffer.clear(); } // release resource fileLock.release(); } catch (IOException e) { e.printStackTrace(); } return builder.toString(); } public static void writeChannel(final File file, final String data, final String encoding) { try(FileOutputStream fos = new FileOutputStream(file); FileChannel fileChannel = fos.getChannel(); FileLock fileLock = fileChannel.lock()/*无参lock()为独占锁*/) { fileChannel.write(ByteBuffer.wrap(data.getBytes(setCharset(encoding)))); } catch (IOException e) { e.printStackTrace(); } }
对于这个锁有如上表述,明确指出此锁用于不同JVM之间的进程来限制文件的读写,而非多线程之间的读写。那么多线程之间读写锁用哪个呢?答案是ReadWriteLock
ReadWriteLock读写锁
public interface ReadWriteLock{……}
顾名思义,此锁作为读写锁用于相同JVM的线程间读写文件操作。而此锁的实现,诸如:可重入的读写锁(ReentrantReadWriteLock)是比较常用的。
public class FileLockUtil { private final static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private final static String DEFAULT_ENCODING = "UTF-8"; public static void write(final File file, final String data, final String encoding) { lock.writeLock().lock(); try(OutputStreamWriter writer = new OutputStreamWriter( new BufferedOutputStream(new FileOutputStream(file)), Charset.forName(setCharset(encoding)))) { writer.write(data); writer.flush(); } catch (IOException e) { e.printStackTrace(); } finally { lock.writeLock().unlock(); } } public static String read(final File file, final String encoding) { lock.readLock().lock(); final StringBuilder builder = new StringBuilder(); try(InputStreamReader reader = new InputStreamReader( new BufferedInputStream(new FileInputStream(file)), Charset.forName(setCharset(encoding)))) { char[] buffer = new char[1024]; int len = -1; while ((len = reader.read(buffer)) != -1) { builder.append(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { lock.readLock().unlock(); } return builder.toString(); } private static String setCharset(final String encoding) { return Optional.ofNullable(encoding).orElse(DEFAULT_ENCODING); } }
继续阅读
微信公众号
分享IT信息技术、北海生活的网站。提供北海本地化的信息技术服务。