在最近的工作中,经常要用到线程,就对线程相关知识稍微看了看,知道并发线程经常引起共享资源冲突,java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持.
可是在工作中,我却碰到了这样的需求,定时抛出线程读写某文件的内容,由于相隔时间很短,我突然想到,会不会在第二次轮循开始对该文件进行读操作的时候,第一次抛出的线程还在对该文件进行写操作,如果有可能,那么第二次读出的数据会是什么样的呢?
怀着这样的疑问,我开始以程序作实验,代码如下:
1.用于写文件的线程
package chb.thread;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
/** *//**
* @author 崔红保
*
* 这个线程用于写文件
*/
public class Thread_writeFile extends Thread...{
public void run()...{
Calendar calstart=Calendar.getInstance();
File file=new File("D:/test.txt");
try ...{
if(!file.exists())
file.createNewFile();
FileWriter fw=new FileWriter(file);
BufferedWriter bw=new BufferedWriter(fw);
for(int i=0;i<1000;i++)...{
sleep(10);
bw.write("这是第"+(i+1)+"行,应该没错哈 ");
}
bw.close();
bw=null;
fw.close();
fw=null;
} catch (IOException e) ...{
e.printStackTrace();
} catch (InterruptedException e) ...{
e.printStackTrace();
}
Calendar calend=Calendar.getInstance();
System.out.println("写文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
}
}
2.用于读文件的线程
package chb.thread;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Calendar;
/** *//**
* @author 崔红保
*
*这个线程用于读文件
*/
public class Thread_readFile extends Thread...{
public void run()...{
try ...{
Calendar calstart=Calendar.getInstance();
sleep(5000);
File file=new File("D:/test.txt");
BufferedReader br=new BufferedReader(new FileReader(file));
String temp=null;
temp=br.readLine();
while(temp!=null)...{
System.out.println(temp);
temp=br.readLine();
}
br.close();
br=null;
Calendar calend=Calendar.getInstance();
System.out.println("读文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
}catch (FileNotFoundException e) ...{
e.printStackTrace();
} catch (IOException e) ...{
e.printStackTrace();
} catch (InterruptedException e) ...{
e.printStackTrace();
}
}
}
3.分别启用两个线程
Thread_writeFile thf3=new Thread_writeFile();
Thread_readFile thf4=new Thread_readFile();
thf3.start();
thf4.start();
4.结果分析
虽然写文件的操作开始5秒钟后,读文件的操作才开始进行,可是读文件的线程并没有读出数据,改变时间,读出的数据也就各不相同.
为了避免以上结果,我们希望在一个线程在操作某个文件的时候,其他线程不能对该文件进行读或写操作,要怎么才能实现呢?利用java提供的synchronized似乎无法完成,因为每个线程是在程序中动态抛出的.郁昧了一天之后,我终于找到了一个解决办法,就是利用java.nio包中的FileChannel对文件进行加锁.
具体实现方法如下:
1.写文件的线程
package chb.thread;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Calendar;
/** *//**
* @author chb
*
*/
public class Thread_writeFile extends Thread...{
public void run()...{
Calendar calstart=Calendar.getInstance();
File file=new File("D:/test.txt");
try ...{
if(!file.exists())
file.createNewFile();
//对该文件加锁
FileOutputStream out=new FileOutputStream(file,true);
FileChannel fcout=out.getChannel();
FileLock flout=null;
while(true)...{
flout=fcout.tryLock();
if(flout!=null)...{
break;
}
else...{
System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");
sleep(100);
}
}
for(int i=1;i<=1000;i++)...{
sleep(10);
StringBuffer sb=new StringBuffer();
sb.append("这是第"+i+"行,应该没啥错哈 ");
out.write(sb.toString().getBytes("utf-8"));
}
flout.release();
fcout.close();
out.close();
out=null;
} catch (IOException e) ...{
e.printStackTrace();
} catch (InterruptedException e) ...{
e.printStackTrace();
}
Calendar calend=Calendar.getInstance();
System.out.println("写文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");
}
}
2.读文件的线程
package chb.thread;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Calendar;
/** *//**
* @author chb
* ?????
*/
public class Thread_readFile extends Thread...{
public void run()...{
try ...{
Calendar calstart=Calendar.getInstance();
sleep(5000);
File file=new File("D:/test.txt");
//给该文件加锁
FileInputStream fis=new FileInputStream(file);
FileChannel fcin=fis.getChannel();
FileLock flin=null;
while(true)...{
flin=fcin.tryLock(0,Long.MAX_VALUE,true);
if(flin!=null)...{
break;
}
else...{
System.out.println("有其他线程正在操作该文件,当前线程休眠1000毫秒");
sleep(1000);
}
}
byte[] buf = new byte[1024];
StringBuffer sb=new StringBuffer();
while((fis.read(buf))!=-1)...{
sb.append(new String(buf,"utf-8"));
buf = new byte[1024];
}
System.out.println(sb.toString());
flin.release();
fcin.close();
fis.close();
fis=null;
Calendar calend=Calendar.getInstance();
System.out.println("读文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"秒");
}catch (FileNotFoundException e) ...{
e.printStackTrace();
} catch (IOException e) ...{
e.printStackTrace();
} catch (InterruptedException e) ...{
e.printStackTrace();
}
}
}
3.分别启用两个线程
Thread_writeFile thf3=new Thread_writeFile();
Thread_readFile thf4=new Thread_readFile();
thf3.start();
thf4.start();
4.结果分析
以上程序在对一个文件执行写操作前,先对该文件加锁,这样其他线程就不能再对该文件操作,等该线程的写操作结束,释放资源,其他线程才可以继续对该文件执行相应的读写操作.
可是,郁昧的是,这段程序在windows下可以正确执行,在linux下却无效.根据<Thinking in Java>上的观点是:对独占锁或者共享锁的支持必须由底层的操作系统提供.
综观我的解决方法,总感觉不太完美,各位如有好的方法来判断一个文件是否正被某个线程使用,希望大家一起分享一下.
你可以通过这个链接引用该篇文章:http://mindyz.bokee.com/viewdiary.15859953.html
分享到:
相关推荐
Java 多线程之并发锁 Java 中的多线程编程是指在一个程序中同时运行多个线程,以提高程序的执行效率和响应速度。在多线程编程中,线程间的同步是非常重要的,因为不同的线程可能会同时访问同一个共享资源,导致数据...
在Java编程语言中,实现多线程文件传输是一种优化程序性能、提高系统资源...在提供的`java多线程文件传输`压缩包中,可能包含了实现这些概念的示例代码,通过分析和学习,可以更好地理解多线程文件传输的原理和实践。
本主题将深入探讨如何在Java多线程环境下实现进度条功能。 首先,理解Java多线程的基本概念至关重要。Java通过Thread类和Runnable接口来支持多线程。创建一个新线程通常有两种方式:继承Thread类并重写run()方法,...
Java多线程是Java编程中不可或缺的一部分,它允许程序同时执行多个任务,提高了程序的效率和响应速度。本文将深入探讨Java多线程的相关概念、线程类和接口的使用,以及线程的同步与互斥。 首先,我们需要理解进程与...
总之,理解和熟练运用这些Java多线程操作对于编写高效、稳定的并发程序至关重要。开发者应始终关注线程安全,避免不必要的数据竞争,并确保程序在多线程环境下的正确性和性能。通过实践和学习,可以更好地掌握Java多...
本文将根据提供的文件信息,深入探讨Java多线程的相关概念和技术细节。 #### 二、Java线程基础 ##### 1. 什么是线程? 线程是进程中的最小执行单元,是进程内部的一次独立的控制流程。在Java中,每个进程至少有一...
标题中的"java 多线程synchronized互斥锁demo"指的是一个示例,展示了如何在多线程环境下使用`synchronized`关键字创建互斥锁,确保同一时间只有一个线程可以访问特定的代码块或方法。 描述中的"一个多线程访问的同...
### JAVA多线程案例教学详析 #### 一、引言 随着计算机技术的发展,多核处理器已经成为标准配置,为了充分利用硬件资源,提高程序的执行效率,多线程编程成为了现代软件开发中不可或缺的一部分。Java作为一种广泛...
Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个小部分,然后创建多个线程同时下载这些部分,以提高下载速度。这种技术在处理大文件或者网络带宽有限的情况下尤其有用,...
这个名为"java多线程源码,仅供参考"的压缩包文件,显然是为了帮助学习者深入理解Java多线程的运行机制。其中的示例程序"BounceThread"可能是一个演示线程交互和同步的经典案例,常用于教授线程的创建、运行以及线程...
Java多线程是Java编程中的一个重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在这个名为"java多线程小汽车运行程序"的项目中,我们可以看到一个利用Java实现的多线程应用程序,可能是模拟汽车...
这个压缩包文件"JAVA多线程模式高清版+DEMO"显然是关于Java多线程设计模式的详细教程,很可能包含了理论讲解、代码示例以及实战DEMO。 在Java多线程编程中,了解和掌握以下知识点至关重要: 1. **线程的创建与启动...
通过阅读提供的"Java多线程设计模式详解.pdf"和"Java多线程设计模式上传文件",开发者可以深入学习这些模式的原理、实现方式以及实际应用场景,从而在实际工作中更好地运用多线程设计模式,提升软件的并发性能和质量...
【标题】:“自己用JAVA做的一个多线程文件服务器” ...通过学习这个项目,读者可以深入理解Java多线程编程、网络编程以及文件服务器的基本原理,同时也是一个很好的实践案例,帮助提升实际开发技能。
Java多线程下载是利用Java编程语言实现的一种高效下载大文件的技术。在传统的单线程下载方式中,如果网络环境不稳定或文件较大,下载过程可能会很慢,甚至中断。而多线程下载则是将文件分割成多个部分,每个部分由一...
### Java多线程编程总结 #### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种手段。 - **进程**:指内存中运行的应用程序,每个...
由于提供的文件内容大部分与Java多线程编程核心技术并无直接关联,而是关于电子书资源的联系方式和说明,因此不能直接从这部分内容中生成关于Java多线程的知识点。但考虑到描述中提到了电子书的标题以及它涉及的主题...
在IT领域,多线程遍历磁盘文件是一项常见的任务,尤其在大数据处理、文件管理系统以及备份恢复等场景中。本文将深入探讨如何利用多线程技术高效地遍历包括隐藏文件和系统文件在内的所有磁盘文件。 首先,我们要理解...
根据提供的文件内容,该文件主要讨论了在Java多线程环境下如何减少内存占用量。文件内容并不完整,且存在 OCR 扫描错误,但我会尝试从中提取与Java多线程和内存管理相关的知识点,并加以详细解释。 ### Java多线程...
标题“java多线程设计模式详解.pdf”中提到的知识点是关于Java多线程编程中设计模式的应用。Java多线程是并发编程的重要组成部分,设计模式则是软件工程中用于解决特定问题的最佳实践。将两者结合起来,意味着此文件...