Java 当一个线程正在访问一个方法时,如何防止其他线程访问该方法?
我想在10个文件中搜索字符串,并将匹配的行写入单个文件。我将每个文件中的匹配行写入10个输出文件(o/p文件1、o/p文件2…),然后使用10个线程将它们复制到单个文件中 但是输出单个文件有混合输出(一行来自o/p文件1,另一行来自o/p文件2等等),因为它被多个线程同时访问。如果我等待所有线程完成,然后写入单个文件,速度会慢得多。 我希望输出文件一次由一个线程写入。我该怎么办 我的源代码:(仅写入单文件方法)Java 当一个线程正在访问一个方法时,如何防止其他线程访问该方法?,java,multithreading,Java,Multithreading,我想在10个文件中搜索字符串,并将匹配的行写入单个文件。我将每个文件中的匹配行写入10个输出文件(o/p文件1、o/p文件2…),然后使用10个线程将它们复制到单个文件中 但是输出单个文件有混合输出(一行来自o/p文件1,另一行来自o/p文件2等等),因为它被多个线程同时访问。如果我等待所有线程完成,然后写入单个文件,速度会慢得多。 我希望输出文件一次由一个线程写入。我该怎么办 我的源代码:(仅写入单文件方法) public void WriteSingle(文件输出、文件最终输出)引发IOEx
public void WriteSingle(文件输出、文件最终输出)引发IOException{
已同步(输出文件){
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
}
在存在该方法之前,请确保flush()
/close()
所有流
并且,正如Xavier在评论中所指出的,确保在同一实例上调用该方法。因为同步发生在每个实例上(在本例中)
在存在该方法之前,请确保flush()
/close()
所有流
并且,正如Xavier在评论中所指出的,确保在同一实例上调用该方法。因为同步发生在每个实例上(在本例中)源代码:
public void WriteSingle(File output_file,File final_output)
throws IOException
{
synchronized(output_file){
try{
wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
int maxCount = (64 * 1024 * 1024) - (32 * 1024);
long size = fc.size();
long position = 0;
while (position < size) {
position += fc.transferTo(position, maxCount, fi);
}
}
public void WriteSingle(文件输出、文件最终输出)
抛出IOException
{
已同步(输出文件){
试试{
等待();
}
捕获(中断异常e){
e、 printStackTrace();
}
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
源代码:
public void WriteSingle(File output_file,File final_output)
throws IOException
{
synchronized(output_file){
try{
wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
int maxCount = (64 * 1024 * 1024) - (32 * 1024);
long size = fc.size();
long position = 0;
while (position < size) {
position += fc.transferTo(position, maxCount, fi);
}
}
public void WriteSingle(文件输出、文件最终输出)
抛出IOException
{
已同步(输出文件){
试试{
等待();
}
捕获(中断异常e){
e、 printStackTrace();
}
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
<>代码> < P>如何使用锁拥有文件编写器类(即在实例上获得锁定,执行任何必要的写入操作,然后释放锁;有点像数据库事务))考虑将文件写入器的实例传递给需要执行写入的对象/方法。(有利于更简单的单元测试/嘲弄).< /P> < P>如何拥有一个带锁的文件编写器类(即在实例上获得锁,执行任何必要的写入,然后释放锁;有点像数据库事务)?考虑将文件写入器的实例传递给需要执行写入的对象/方法。(还有更简单的单元测试/模拟的好处)。如果我理解这一点,您想防止两个线程写入同一个文件吗
最简单的方法是锁定文件本身,而不是文件
对象:
public void WriteSingle(File output_file, File final_output) throws IOException {
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
FileLock lock = fi.lock(); // Get lock here, blocks until file is closed
fc.transferTo(0, fc.size(), fi);
fc.close();
fi.close();
fo.close();
fs.close();
}
如果我理解这一点,您想阻止两个线程写入同一个文件吗
最简单的方法是锁定文件本身,而不是文件
对象:
public void WriteSingle(File output_file, File final_output) throws IOException {
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
FileLock lock = fi.lock(); // Get lock here, blocks until file is closed
fc.transferTo(0, fc.size(), fi);
fc.close();
fi.close();
fo.close();
fs.close();
}
public synchronized void WriteSingle(文件输出、文件最终输出)引发IOException{
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
如果这不起作用,那么您可能正在使用多个实例写入文件。在这种情况下,您可以尝试使用如下类锁:
public void WriteSingle(File output_file,File final_output) throws IOException {
synchronized(getClass()) {
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
int maxCount = (64 * 1024 * 1024) - (32 * 1024);
long size = fc.size();
long position = 0;
while (position < size) {
position += fc.transferTo(position, maxCount, fi);
}
}
}
public void WriteSingle(文件输出、文件最终输出)引发IOException{
已同步(getClass()){
System.out.println(“写入单个文件”);
FileOutputStream fo=新的FileOutputStream(最终输出,true);
FileChannel fi=fo.getChannel();
FileInputStream fs=新的FileInputStream(输出文件);
FileChannel fc=fs.getChannel();
int maxCount=(64*1024*1024)-(32*1024);
长尺寸=fc.size();
长位置=0;
while(位置<大小){
位置+=fc.transferTo(位置,最大计数,fi);
}
}
}
这并不理想,但它应该给我们一个关于您的代码正在做什么的提示
如果这两种方法都不起作用,那么您的通用编程逻辑可能是错误的,并且问题可能没有太大的影响
public void WriteSingle(File output_file,File final_output) throws IOException {
synchronized(getClass()) {
System.out.println("Writing Single file");
FileOutputStream fo = new FileOutputStream(final_output,true);
FileChannel fi = fo.getChannel();
FileInputStream fs = new FileInputStream(output_file);
FileChannel fc = fs.getChannel();
int maxCount = (64 * 1024 * 1024) - (32 * 1024);
long size = fc.size();
long position = 0;
while (position < size) {
position += fc.transferTo(position, maxCount, fi);
}
}
}