“This is the 16th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
Pipe
A Java NIO Pipe is a one-way data connection between two threads, and a Pipe has a source channel and a sink channel. Data will be dropped into the Sink channel and read from the source channel.
1. Create a channel
Open the Pipe with the pipe.open () method
Pipe pipe = Pipe.open();
Copy the code
2. Write channel
To write data to the pipe, you need to access the Sink channel.
Pipe.Sinkchannel sinkChannel = pipe.sink();
Copy the code
Write data to Sinkchannel by calling Sinkchannel’s write() method:
String newData = "New String to write to file .." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.alloacte(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()) {
sinkChannel.write(buf);
}
Copy the code
3. Read data from the pipe
To read the data from the pipe, access the source channel like this:
Pipe.SourceChannel sourceChannel = pipe.source();
Copy the code
Call the read() method on the source channel to read the data:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = sourceChannel.read(buf);
Copy the code
The int returned by the read() method tells us how many bytes were read into the buffer.
4, sample
We will read and write data through Pipe, Sink as shown in the following example:
public class PipeDemo {
public static void main(String[] args) throws IOException {
// 1 get the pipe
Pipe pipe = Pipe.open();
// 2 Get the sink channel
Pipe.SinkChannel sinkChannel = pipe.sink();
// 3 Create a buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("ha ha!".getBytes(StandardCharsets.UTF_8));
buffer.flip();
// 4 Write data
sinkChannel.write(buffer);
// 5 source channel
Pipe.SourceChannel sourceChannel = pipe.source();
// 6 Create a buffer and read the data
ByteBuffer buffer2 = ByteBuffer.allocate(1024);
//buffer2.flip();
int len = sourceChannel.read(buffer2);
String str = new String(buffer2.array(), 0, len);
System.out.println(str);
// 7 Close the channelsinkChannel.close(); sourceChannel.close(); }}Copy the code
FileLock
FileLock profile
File locking is very common in the OS. If multiple programs access and modify the same file at the same time, it is easy to cause problems when English file data is not synchronized. By adding a lock to a file, only one program can modify the file in the same event, or both programs can only read the file, which solves the synchronization problem.
File locks are process-level, not thread-level. File locks can solve the problem that multiple threads concurrently access and modify the same file, but can not solve the problem that multiple threads concurrently access and modify the same file.
When using a file lock, multiple users in the same process can access and modify the file at the same time.
The file lock is held by the JVM instance of which the current program lock belongs, and once the file lock is acquired (locks the file), it is released either by calling Release () or closing the corresponding FileChannel object, or by exiting the current JVM.
Once a process (such as a JVM instance) locks a file, the process cannot lock the file again until the lock is released, that is, file locks that the JVM instance has placed on the same file cannot overlap (the process level cannot repeatedly acquire locks on the same file).
2. File lock allocation
Exclusive lock: After an exclusive lock is added to a file, the process can read and write the file. The process exclusively reads and writes the file. Other processes cannot read and write the file.
Shared lock: a process locks a file so that other processes can access the file, but these processes can only read the file but cannot write to it. Threads are safe. This file can only be read, not written, as long as another process holds the shared lock. (Actually, you can only share read, not write).
3. Use examples
// Create a FileChannel object. File locks can only be used with a FileChannel object
String pathName = "/xxx/01.txt";
FileChannel fileChannel = new FileOutputStream(pathName).getChannel();
// Lock the file
FileLock lock = fileChannel.lock();
// Read and write to this file
/ /...
/ / releases the lock
lock.release();
Copy the code
The file lock is used through the FileChannel object.
4, get file lock method
There are 4 ways to obtain a file lock:
-
Lock () // Lock the entire file. Default is exclusive lock
-
Lock (Long position, long size, Boolean shared) // Customize lock mode. The first two parameters specify the part to be locked (you can lock only parts of the file), and the third parameter value specifies whether the lock is shared.
-
Trylock () // Lock the entire file. Default is exclusive lock.
-
Trylock (long position, long size, Boolean shared) // Customize lock mode. If the lock is specified as a shared lock, other processes can read the file, but no process can write the file. If a process view writes the file, an exception will be thrown.
5. The difference between lock and trylock
Lock is blocking. If the file lock is not acquired, the current thread will be blocked until the file lock is acquired.
Trylock is the same as lock, except that trylock is non-blocking. Trylock attempts to acquire a file lock and returns the lock object on success. Otherwise, null is returned and the current thread is not blocked.
FileLock two methods
Boolean isShared() // whether this file lock isShared
Boolean isValid() // Whether this file lock is still valid
On some OS, after a file is locked, channel mapping cannot be used for that file.
7. Complete example
public class FileLockDemo2 {
public static void main(String[] args) throws IOException {
String input = "hello!";
System.out.println(input);
ByteBuffer buffer = ByteBuffer.wrap(input.getBytes(StandardCharsets.UTF_8));
String pathName = "/xxx/01.txt";
Path path = Paths.get(pathName);
FileChannel fileChannel = FileChannel.open(path,
StandardOpenOption.WRITE, StandardOpenOption.APPEND);
fileChannel.position(fileChannel.size() - 1);
/ / lock
FileLock lock = fileChannel.lock();
// If the lock is shared, subsequent write operations cannot be performed
//FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true);
System.out.println("isShared: " + lock.isShared());
fileChannel.write(buffer);
fileChannel.close();
readFile(pathName);
}
private static void readFile(String pathName) throws IOException {
FileReader fileReader = new FileReader(pathName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String str = bufferedReader.readLine();
System.out.println("Read content:");
while(str ! =null) {
System.out.println(""+ str); str = bufferedReader.readLine(); } fileReader.close(); bufferedReader.close(); }}Copy the code