`
ihuashao
  • 浏览: 4720559 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

多线程并发思考--文件加锁

阅读更多

多线程并发思考--文件加锁

在最近的工作中,经常要用到线程,就对线程相关知识稍微看了看,知道并发线程经常引起共享资源冲突,java以提供关键字synchronized的形式,为防止资源冲突提供了内置支持.

可是在工作中,我却碰到了这样的需求,定时抛出线程读写某文件的内容,由于相隔时间很短,我突然想到,会不会在第二次轮循开始对该文件进行读操作的时候,第一次抛出的线程还在对该文件进行写操作,如果有可能,那么第二次读出的数据会是什么样的呢?

怀着这样的疑问,我开始以程序作实验,代码如下:

1.用于写文件的线程

packagechb.thread;

importjava.io.BufferedWriter;
importjava.io.File;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.util.Calendar;

/***//**
*
@author崔红保
*
*这个线程用于写文件
*/

publicclassThread_writeFileextendsThread...{
publicvoidrun()...{
Calendarcalstart
=Calendar.getInstance();
Filefile
=newFile("D:/test.txt");
try...{
if(!file.exists())
file.createNewFile();
FileWriterfw
=newFileWriter(file);
BufferedWriterbw
=newBufferedWriter(fw);
for(inti=0;i<1000;i++)...{
sleep(
10);
bw.write(
"这是第"+(i+1)+"行,应该没错哈 ");
}

bw.close();
bw
=null;
fw.close();
fw
=null;
}
catch(IOExceptione)...{
e.printStackTrace();
}
catch(InterruptedExceptione)...{
e.printStackTrace();
}

Calendarcalend
=Calendar.getInstance();
System.out.println(
"写文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
}


}

2.用于读文件的线程

packagechb.thread;

importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileNotFoundException;
importjava.io.FileReader;
importjava.io.IOException;
importjava.util.Calendar;

/***//**
*
@author崔红保
*
*这个线程用于读文件
*/

publicclassThread_readFileextendsThread...{
publicvoidrun()...{
try...{
Calendarcalstart
=Calendar.getInstance();
sleep(
5000);
Filefile
=newFile("D:/test.txt");
BufferedReaderbr
=newBufferedReader(newFileReader(file));
Stringtemp
=null;
temp
=br.readLine();
while(temp!=null)...{
System.out.println(temp);
temp
=br.readLine();
}


br.close();
br
=null;
Calendarcalend
=Calendar.getInstance();
System.out.println(
"读文件共用了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"毫秒");
}
catch(FileNotFoundExceptione)...{
e.printStackTrace();
}
catch(IOExceptione)...{
e.printStackTrace();
}
catch(InterruptedExceptione)...{
e.printStackTrace();
}

}

}

3.分别启用两个线程

Thread_writeFilethf3=newThread_writeFile();
Thread_readFilethf4
=newThread_readFile();
thf3.start();
thf4.start();

4.结果分析

虽然写文件的操作开始5秒钟后,读文件的操作才开始进行,可是读文件的线程并没有读出数据,改变时间,读出的数据也就各不相同.

为了避免以上结果,我们希望在一个线程在操作某个文件的时候,其他线程不能对该文件进行读或写操作,要怎么才能实现呢?利用java提供的synchronized似乎无法完成,因为每个线程是在程序中动态抛出的.郁昧了一天之后,我终于找到了一个解决办法,就是利用java.nio包中的FileChannel对文件进行加锁.

具体实现方法如下:

1.写文件的线程

packagechb.thread;

importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.nio.channels.FileChannel;
importjava.nio.channels.FileLock;
importjava.util.Calendar;

/***//**
*
@authorchb
*
*/

publicclassThread_writeFileextendsThread...{
publicvoidrun()...{
Calendarcalstart
=Calendar.getInstance();
Filefile
=newFile("D:/test.txt");
try...{
if(!file.exists())
file.createNewFile();

//对该文件加锁
FileOutputStreamout=newFileOutputStream(file,true);
FileChannelfcout
=out.getChannel();
FileLockflout
=null;
while(true)...{
flout
=fcout.tryLock();
if(flout!=null)...{
break;
}

else...{
System.out.println(
"有其他线程正在操作该文件,当前线程休眠1000毫秒");
sleep(
100);
}

}


for(inti=1;i<=1000;i++)...{
sleep(
10);
StringBuffersb
=newStringBuffer();
sb.append(
"这是第"+i+"行,应该没啥错哈 ");
out.write(sb.toString().getBytes(
"utf-8"));
}



flout.release();
fcout.close();
out.close();
out
=null;
}
catch(IOExceptione)...{
e.printStackTrace();
}
catch(InterruptedExceptione)...{
e.printStackTrace();
}

Calendarcalend
=Calendar.getInstance();
System.out.println(
"写文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"");
}

}

2.读文件的线程

packagechb.thread;

importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.IOException;
importjava.nio.channels.FileChannel;
importjava.nio.channels.FileLock;
importjava.util.Calendar;

/***//**
*
@authorchb
*���ļ�
*/

publicclassThread_readFileextendsThread...{
publicvoidrun()...{
try...{
Calendarcalstart
=Calendar.getInstance();
sleep(
5000);
Filefile
=newFile("D:/test.txt");

//给该文件加锁
FileInputStreamfis=newFileInputStream(file);
FileChannelfcin
=fis.getChannel();
FileLockflin
=null;
while(true)...{
flin
=fcin.tryLock(0,Long.MAX_VALUE,true);
if(flin!=null)...{
break;
}

else...{
System.out.println(
"有其他线程正在操作该文件,当前线程休眠1000毫秒");
sleep(
1000);
}

}

byte[]buf=newbyte[1024];
StringBuffersb
=newStringBuffer();
while((fis.read(buf))!=-1)...{
sb.append(
newString(buf,"utf-8"));
buf
=newbyte[1024];
}


System.out.println(sb.toString());

flin.release();
fcin.close();
fis.close();
fis
=null;

Calendarcalend
=Calendar.getInstance();
System.out.println(
"读文件共花了"+(calend.getTimeInMillis()-calstart.getTimeInMillis())+"");
}
catch(FileNotFoundExceptione)...{
e.printStackTrace();
}
catch(IOExceptione)...{
e.printStackTrace();
}
catch(InterruptedExceptione)...{
e.printStackTrace();
}

}

}

3.分别启用两个线程

Thread_writeFilethf3=newThread_writeFile();
Thread_readFilethf4
=newThread_readFile();
th
分享到:
评论

相关推荐

    多线程并发编程-同步与互斥-原⼦变量-并发和⽆锁 数据结构

    多线程并发编程-同步与互斥-原子变量-并发和无锁数据结构 多线程并发编程是提高认程序性能的核心技术,但它也增加了编程的复杂性。因此,系统理解和掌握多线程并发编程的技巧变得尤为重要。本章将从多线程编程的...

    Tesseract OCR多线程并发识别案例

    在处理大量图像或需要快速响应时间的应用场景中,多线程并发识别可以显著提升效率。以下将详细介绍如何利用Tesseract OCR实现多线程并发识别,以及可能涉及的相关技术点。 首先,理解Tesseract OCR的基本工作原理是...

    并发服务器-多线程服务器详解

    - **共享资源**:同一进程中的多个线程共享内存空间、文件描述符等资源,这意味着它们可以直接访问相同的全局变量、堆数据等,提高了数据交互效率。 - **开销较小**:相对于创建新进程而言,创建新线程的开销较小。...

    多线程精品资源--高并发-高可靠-高性能three-high-import导入系统-高并发多线程进阶.zip

    "多线程精品资源--高并发-高可靠-高性能three-high-import导入系统-高并发多线程进阶.zip" 这个压缩包文件名暗示了其内容可能包含了一系列关于如何在复杂系统中有效地利用多线程来达到高并发、高可靠性和高性能的...

    java 多线程并发实例

    在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...

    高并发多线程处理demo-java.rar

    在Java编程领域,高并发和多线程是关键的技术之一,尤其在服务器端应用和大数据处理中至关重要。这个"高并发多线程处理demo-java.rar"压缩包提供了一个实际的Java实现,展示了如何构建一个并发队列来接收数据,并...

    模拟jdbc多线程竞争资源---【Eclipse项目】

    本项目“模拟jdbc多线程竞争资源---【Eclipse项目】”着重于探讨在多线程环境下,如何处理并发访问数据库时可能出现的资源竞争问题。下面将详细介绍这个项目中的关键知识点。 1. JDBC基础: JDBC是Java平台的标准...

    基于Qt的多线程并发服务器

    文件列表中的`tcpserver2`可能是一个示例项目或者源代码文件,它展示了如何在Qt环境中实现一个多线程并发服务器的具体细节。通过分析这个文件,你可以更深入地理解如何在实践中应用上述概念。 总的来说,基于Qt的多...

    多线程精品资源--多线程与高并发.zip

    在IT行业中,多线程和高并发是两个关键的概念,特别是在服务器端开发、分布式系统以及高性能计算领域。本文将深入探讨这两个主题,并结合资源包"多线程精品资源--多线程与高并发.zip"中的内容,提供相关知识点的详细...

    易语言源码多文件多线程传送--.7z

    在这个“易语言源码多文件多线程传送--.7z”压缩包中,我们可以推测包含的是易语言编写的源代码,这些源代码实现了多文件的多线程传输功能。 在计算机编程中,多线程技术是一项关键技能,特别是在处理大量数据或...

    WEBAPI多线程并发测试工具

    标题"WEBAPI多线程并发测试工具"指出,这是一个专门针对Web API进行多线程并发测试的工具。Web API通常指的是应用程序接口,它们允许不同的服务之间进行通信,以实现数据交换和功能整合。多线程并发测试则是验证在多...

    Java多线程实战精讲-带你一次搞明白Java多线程高并发

    Java多线程实战精讲是Java开发者必备的技能之一,特别是在处理高并发场景时,它的重要性不言而喻。本文将深入探讨Java多线程的相关知识点,帮助你全面理解并掌握这一核心概念。 1. **线程基础** - **线程定义**:...

    windowsC++多线程加锁信号量共享内存

    在Windows环境下,C++开发中,多线程技术常常被用来提升程序的执行效率,特别是在处理大量并发任务时。然而,多线程编程也带来了一些挑战,如数据竞争和死锁问题,这些问题需要通过同步机制来解决。在这个场景下,...

    MFC多线程编程实例----多线程画线源码

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC) 库进行多线程编程,特别是关注在MFC环境中创建和管理多个线程来实现并发画线的实例。MFC是一个面向对象的C++库,它为Windows应用程序开发提供了...

    Java 模拟线程并发

    最后,Java并发库还包含了很多其他有用的工具,如Semaphore(信号量)用于控制同时访问特定资源的线程数量,CyclicBarrier(循环屏障)和CountDownLatch(计数器门锁)用于多线程间的协作,以及Lock接口及其实现如...

    嵌入式实时操作系统的多线程计算--基于ThreadX和ARM--随书光盘(自己备份)

    Express Logic's ThreadX for Win32 Demo Using Visual C/C++ This demo program is intended for use with the book titled "Real-Time Embedded Multithreading: Using ThreadX and ARM" by Edward L....

    多线程服务器平台-phpstudy

    在Web开发中,多线程技术能够有效地利用系统资源,特别是在高并发场景下,能够更好地响应用户请求,提供更高效的性能。 【描述】"支持多线程编码"意味着phpstudy不仅是一个运行环境,还提供了对多线程编程的支持。...

    (中英文)-POSIX多线程程序设计-Programming with POSIX Threads

    - 线程是操作系统内核调度的基本单位,一个进程中可以包含多个线程,它们共享同一地址空间,可以并发执行,提高了程序的并行性和执行效率。 2. **线程创建与管理** - `pthread_create()`函数用于创建新的线程,它...

Global site tag (gtag.js) - Google Analytics