IDEA 多线程debug调试
多线程修改同一个文件作为演示
1、设置IDEA的中断方式为线程
2、设置文件锁
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
/**
* @program: lockfile
* @create: 2020-06-12 22:31
*/
public class LockFile {
public void updateFile() throws Exception {
File lockFile = new File("E:\\Idea_workspace\\lockfile\\.lock");
if (!lockFile.exists()) {
lockFile.createNewFile();
}
FileOutputStream fileOutputStream = null;
FileChannel fileChannel = null;
FileLock fileLock = null;
try {
fileOutputStream = new FileOutputStream(lockFile, true);
fileChannel = fileOutputStream.getChannel();
while (true) {
try {
fileLock = fileChannel.lock();
break;
} catch (OverlappingFileLockException e) {
System.out.println("文件已锁定,等待1s");
Thread.sleep(1000);
}
}
for (int i = 0; i < 10; i++) {
fileOutputStream.write(String.valueOf(i).getBytes());
fileOutputStream.write(" ".getBytes());
}
fileOutputStream.write("\r\n".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
close(fileOutputStream, fileChannel, fileLock);
}
}
/**
* 释放锁及关闭流
*
* @param fileOutputStream
* @param fileChannel
* @param fileLock
*/
private void close(FileOutputStream fileOutputStream, FileChannel fileChannel, FileLock fileLock) {
if (fileLock != null && fileLock.isValid()) {
try {
fileLock.release();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileChannel != null) {
try {
fileChannel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、线程类
import java.io.IOException;
/**
* @program: lockfile
* @create: 2020-06-12 22:51
*/
public class MyTread implements Runnable {
private String name;
private LockFile lockFile = new LockFile();
public MyTread(String name) {
this.name = name;
}
public void run() {
try {
lockFile.updateFile();
} catch (Exception e) {
e.printStackTrace();
}
}
}
4、打断点
4、启动线程
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(new MyTread("第" + i + "线程")).start();
}
}
}
5、进入线程断点
6、断点调试
上图可以看到开启的10个线程,✔的是当前线程,⭕的是等待线程,你可以双击切换线程,每个线程都可以使用F8单步调试。这样能够很好的控制线程的执行顺序。
在本案例中,当其中一个线程获取到文件锁时,其他线程都进入各自的while循环,等待获取文件锁。这里需要捕获OverlappingFileLockException异常。
有什么问题欢迎大家留言和指出,谢谢!