java多線程文件
Ⅰ java多線程同時讀取一個文件,這個方法可行嗎
不可行。每次讀取文件都需要創建緩存文件流,很占內存,而且多次讀取實際上也是一個文件,還不如直接讀取文件,之後通過條件多次獲取需要的內容來的實際。
可以通過BufferedReader 流的形式進行流緩存,之後通過readLine方法獲取到緩存的內容。
BufferedReader bre = null;
try {
String file = "D:/test/test.txt";
bre = new BufferedReader(new FileReader(file));//此時獲取到的bre就是整個文件的緩存流
while ((str = bre.readLine())!= null) // 判斷最後一行不存在,為空結束循環
{
System.out.println(str);//原樣輸出讀到的內容,此處可以添加條件進行不同的處理
};
備註: 流用完之後必須close掉,如上面的就應該是:bre.close(),否則bre流會一直存在,直到程序運行結束。
Ⅱ java大數據 多線程寫文件
1、採用public static的變數存儲這一數值,每個線程都往這一共有靜態變數里寫入已復制大小。 2、採用Callable方式實現多線程,將結果作為返回值返回到主線程。這一方法只能在所有子線程都完成之後才能通過future獲取。
Ⅲ 要用java實現多線程的文件上傳該如何去做
的資源消耗,因此,在進行同類事情,需要進行互相的通訊等等事情的時候,都採用線程來進行處理。
對於只做固定的一件事情(比如:計算1+2+3+...+9999999)來說,其性能上不會比採用單線程的整體效率高,原因是,同時都是要做這么多運算,採用多線程的話,系統在進行線程調度的過程中喙浪費一些資源和時間,從而性能上下降。
那麼,多線程是否就沒有存在的意義了呢?答案當然不是的。多線程還是有存在的價值的,我們在寫輸入流輸出流,寫網路程序等等的時候,都會出現阻塞的情況,如果說,我們不使用多線程的話,從A中讀數據出來的時候,A因為沒有準備好,而整個程序阻塞了,其他的任何事情都沒法進行。如果採用多線程的話,你就不用擔心這個問題了。還舉個例子:游戲中,如果A角色和B角色採用同一個線程來處理的話,那麼,很有可能就會出現只會響應A角色的操作,而B角色就始終被佔用了的情況,這樣,玩起來肯定就沒勁了。
因此,線程是有用的,但也不是隨便亂用,亂用的話,可能造成性能的低下,它是有一點的適用范圍的,一般我認為:需要響應多個人的事情,從設計上需要考慮同時做一些事情(這些事情很多情況下可能一點關系都沒有,也有可能有一些關系的)。
使用多線程的時候,如果某些線程之間涉及到資源共享、互相通訊等等問題的時候,一定得注意線程安全的問題,根據情況看是不是需要使用synchronized關鍵字。
另外,站長團上有產品團購,便宜有保證
Ⅳ 求多線程讀取一個文件,然後寫到另外一個文件中的Java實現。
這個是我寫的三個類,用於多線程操作讀取文件內容和寫入文件內容,不知道是不是你合你味口。
________________第一個類______讀取內容__寫入內容____________________
package pro;
import java.io.*;
public class ReadFileToWriteOtherFile {
private File oldFile;
private File newFile;
private BufferedReader br;
private BufferedWriter bw;
private String totalString="";
private Boolean flag=true; //用於標記文件名是否存在 true表示存在
public ReadFileToWriteOtherFile()
{
oldFile=null;
newFile=null;
br=null;
bw=null;
System.out.println("初始化成功");
}
public void readInfoFromFile(String fileName)
{
System.out.println("開始讀取");
try
{
oldFile=new File(fileName);
if(oldFile.exists()) //如果文件存在
{
System.out.println("存在");
br=new BufferedReader(new FileReader(oldFile));
String info=br.readLine(); //讀取一行
while(info!=null)
{
totalString+=info; //將讀取到的一行添加到totalString中
info=br.readLine(); //再讀取下一行
//System.out.println(totalString);
}
System.out.println("讀取完成,准備寫入…………");
}
else //如果文件不存在
{
System.out.println("文件不存在");
flag=false; //標記該文件不存在
}
// System.out.println("totalString="+totalString);
}
catch(FileNotFoundException e)
{
System.out.println(e);System.out.println("開始讀取中1");
}
catch(IOException e)
{System.out.println(e);System.out.println("開始讀取中2");}
}
public void writeInfoToFile(String fileName)
{
if(!flag) //如果標記前面的文件不存在,則return
{
flag=true; //改回原來的文件標記符
return;
}
try
{
newFile=new File(fileName);
if(newFile.exists()) //如果存在,不用創建新文件
{
System.out.println("文件存在,可以寫入!");
}
else //如果不存在,則創建一個新文件
{
System.out.println("文件不存在,准備創建新文件");
newFile.createNewFile();
System.out.println("文件創建成功,可以寫入");
}
bw=new BufferedWriter(new FileWriter(newFile,true));
// System.out.println("totalString="+totalString);
bw.write(totalString,0,totalString.length());
bw.flush(); //刷新緩沖區
System.out.println("寫入完成");
totalString="\r\t"; //清空原來的字元串
}
catch(FileNotFoundException e)
{System.out.println(e);}
catch(IOException e)
{System.out.println(e);}
}
}
________________第二個類______一個自定義的線程類____________________
package pro;
import java.lang.Thread;
public class MyThread extends Thread
{
private int index; //用於數組的位置
private String[] fileNames; //定義一個字元串數組
ReadFileToWriteOtherFile bftwo=new ReadFileToWriteOtherFile(); //定義前面的自定義類
public MyThread(String[] fileNames,int index) //index表示數組位置標號
{
this.index=index;
this.fileNames=fileNames;
}
public void run()
{
bftwo.readInfoFromFile(fileNames[index]);//傳入數組中的字元串參數
bftwo.writeInfoToFile("b.txt"); //傳入寫入的目的地文件
//index++; //數組位置加1
System.out.println("==============");//分隔線
}
}
________________第三個類______主程序____________________
package pro;
//import org.springframework.context.ApplicationContext;
//import org.springframework.context.support.;
import java.io.*;
public class BeanRunApp {
/**
* Method main
*
*
* @param args
*
*/
public static void main(String[] args)
{
/* ApplicationContext apc=new ("beans.xml");
ClassRoom croom=(ClassRoom)apc.getBean("classRoom");
croom.out();
System.out.println("over");
*/
long startTime=System.currentTimeMillis();
String[] a={"a.txt","c.txt","d.txt","e.txt"}; //用一個符品數組保存文件名
for(int i=0;i<a.length;i++) //用數組的長度來作為循環條件
{ //把這個數組和i的值作為構造函數傳入線程類
MyThread myth=new MyThread(a,i);
System.out.println("--------------------------------");
myth.start(); //執行
System.out.println("當前的線程是:"+myth.getName());
}
long endTime=System.currentTimeMillis();
System.out.println("耗時:"+(endTime-startTime)+"毫秒");
}
}
Ⅳ 某公司面試題java11使用並發多線程加速下載文件,如何寫
先建一個用於下載文件的多線程類,通常要指明下載文件的位置(URL)和拍胡文件名以及保存到本地的路徑
public class FileDownloader implements Runnable
{
private static File file;//要下載的文件
private static String url;//文件所在URL
private static File storagePath;//保存路徑
public static void initialize(File file, String url, File storagePath)//初始化靜態欄位,初始化的代碼不用我寫吧
}
然後,指明同步塊,目的是讓各個線程共享一個文件資源,那樣它們可以知道同一個文件的下載狀況(即獲取其他線程下載文件到哪個位置,以防重復下載)
public synchronized void fileDownload()//此方法用於下載文件,一般的Java程序員都會寫,實在不會我可以幫你補上
或者
public void fileDownload(){
synchronized(file){
synchronized(url){
synchronized(storagePath){
}}}}//給每仿賀橋個字備猛段加上同步塊
run()方法的實現就以自己的喜好去寫吧,只要裡面調用了fileDownload()方法就行。
public void run(){
…
fileDownload();//下載文件
…
}
然後,在主類的main方法中創建一個多線程數組:
Runnable[] fds=new FileDownloader[線程數量];//fds為file_downloaders縮寫
Thread[] threads=new Thread[線程數量];
最後使用循環把所有的線程逐一啟動。
for(int i=0;i<線程數量;i++){
threads[i]=new Thread(fds[i]);
threads[i].start();
}
Ⅵ java多線程讀寫文件
public static void main(String[] args) {
File data = new File("data.txt");
try {
InputStreamReader read = new InputStreamReader(new FileInputStream(
data), "UTF-8");
final BufferedReader bufferedReader = new BufferedReader(read);
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
String lineTXT = null;
synchronized (bufferedReader) {
try {
while ((lineTXT = bufferedReader.readLine()) != null) {
System.out.println(Thread.currentThread()+":"+lineTXT);
bufferedReader.notify();
bufferedReader.wait();
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
bufferedReader.notifyAll();
}
}
}
}).start();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Ⅶ 使用Java多線程實現任務分發
多線程下載由來已久 如 FlashGet NetAnts 等工具 它們都是依懶於 HTTP 協議的支持(Range 欄位指定請求內容範圍) 首先能讀取出請求內容 (即欲下載的文件) 的大小 劃分出若干區塊 把區塊分段分發給每個線程去下載 線程從本段起始處下載數據及至段尾 多個線程下載的內容最終會寫入到同一個文件中
只研究有用的 工作中的需求 要把多個任務納凱分派給Java的多個線程去執行 這其中就會有一個任務列表指派到線程的策略思考 已知 一個待執行的任務列表 指定要啟動的線程數 問題是 每個線程實際要執行哪些任務
使用Java多線程實現這種任務分發的策略是 任務列表連續按線程數分段 先保證每線程平均能分配到的任務數 餘下的任務從前至後依次附加到線程中——只是數量上 實際每個線程執行的任務都還是連續的 如果出現那種僧多(線程) 粥(任務) 少的情況 實際啟動的線程數就等於任務數 一挑一 這里只實現了每個線程各掃自謹宴家門前雪 動作快的完成後眼見別的線程再累都是愛莫能助
實現及演示代碼如下 由三個類實現 寫在了一個 Java 文件中 TaskDistributor 為任務分發器 Task 為待執行的任務 WorkThread 為自定的工作洞晌喚線程 代碼中運用了命令模式 如若能配以監聽器 用上觀察者模式來控制 UI 顯示就更絕妙不過了 就能實現像下載中的區塊著色跳躍的動感了 在此定義下一步的著眼點了
代碼中有較為詳細的注釋 看這些注釋和執行結果就很容易理解的 main() 是測試方法
package mon;import java util ArrayList;import java util List;/*** 指派任務列表給線程的分發器* @author Unmi* QQ: Email: * MSN: */public class TaskDistributor {/*** 測試方法* @param args*/public static void main(String[] args) {//初始化要執行的任務列表List taskList = new ArrayList();for (int i = ; i < ; i++) {taskList add(new Task(i));}//設定要啟動的工作線程數為 個int threadCount = ;List[] taskListPerThread = distributeTasks(taskList threadCount);System out println( 實際要啟動的工作線程數 +taskListPerThread length);for (int i = ; i < taskListPerThread length; i++) {Thread workThread = new WorkThread(taskListPerThread[i] i);workThread start();}}/*** 把 List 中的任務分配給每個線程 先平均分配 剩於的依次附加給前面的線程* 返回的數組有多少個元素 (List) 就表明將啟動多少個工作線程* @param taskList 待分派的任務列表* @param threadCount 線程數* @return 列表的數組 每個元素中存有該線程要執行的任務列表*/public static List[] distributeTasks(List taskList int threadCount) {// 每個線程至少要執行的任務數 假如不為零則表示每個線程都會分配到任務int minTaskCount = taskList size() / threadCount;// 平均分配後還剩下的任務數 不為零則還有任務依個附加到前面的線程中int remainTaskCount = taskList size() % threadCount;// 實際要啟動的線程數 如果工作線程比任務還多// 自然只需要啟動與任務相同個數的工作線程 一對一的執行// 畢竟不打算實現了線程池 所以用不著預先初始化好休眠的線程int actualThreadCount = minTaskCount > ? threadCount : remainTaskCount;// 要啟動的線程數組 以及每個線程要執行的任務列表List[] taskListPerThread = new List[actualThreadCount];int taskIndex = ;//平均分配後多餘任務 每附加給一個線程後的剩餘數 重新聲明與 remainTaskCount//相同的變數 不然會在執行中改變 remainTaskCount 原有值 產生麻煩int remainIndces = remainTaskCount;for (int i = ; i < taskListPerThread length; i++) {taskListPerThread[i] = new ArrayList();// 如果大於零 線程要分配到基本的任務if (minTaskCount > ) {for (int j = taskIndex; j < minTaskCount + taskIndex; j++) {taskListPerThread[i] add(taskList get(j));}taskIndex += minTaskCount;}// 假如還有剩下的 則補一個到這個線程中if (remainIndces > ) {taskListPerThread[i] add(taskList get(taskIndex++));remainIndces ;}}// 列印任務的分配情況for (int i = ; i < taskListPerThread length; i++) {System out println( 線程 + i + 的任務數 +
taskListPerThread[i] size() + 區間[ + taskListPerThread[i] get( ) getTaskId() + + taskListPerThread[i] get(taskListPerThread[i] size() ) getTaskId() + ] );}return taskListPerThread;}}/*** 要執行的任務 可在執行時改變它的某個狀態或調用它的某個操作* 例如任務有三個狀態 就緒 運行 完成 默認為就緒態* 要進一步完善 可為 Task 加上狀態變遷的監聽器 因之決定UI的顯示*/class Task {public static final int READY = ;public static final int RUNNING = ;public static final int FINISHED = ;private int status;//聲明一個任務的自有業務含義的變數 用於標識任務private int taskId;//任務的初始化方法public Task(int taskId){this status = READY;this taskId = taskId;}/*** 執行任務*/public void execute() {// 設置狀態為運行中setStatus(Task RUNNING);System out println( 當前線程 ID 是 + Thread currentThread() getName()+ | 任務 ID 是 +this taskId);// 附加一個延時try {Thread sleep( );} catch (InterruptedException e) {e printStackTrace();}// 執行完成 改狀態為完成setStatus(FINISHED);}public void setStatus(int status) {this status = status;}public int getTaskId() {return taskId;}}/*** 自定義的工作線程 持有分派給它執行的任務列表*/class WorkThread extends Thread {//本線程待執行的任務列表 你也可以指為任務索引的起始值private List taskList = null;private int threadId;/*** 構造工作線程 為其指派任務列表 及命名線程 ID* @param taskList 欲執行的任務列表* @param threadId 線程 ID*/public WorkThread(List taskList int threadId) {this taskList = taskList;this threadId = threadId;}/*** 執行被指派的所有任務*/public void run() {for (Task task : taskList) {task execute();}}}
執行結果如下 注意觀察每個Java多線程分配到的任務數量及區間 直到所有的線程完成了所分配到的任務後程序結束
線程 的任務數 區間[ ]線程 的任務數 區間[ ]線程 的任務數 區間[ ]線程 的任務數 區間[ ]線程 的任務數 區間[ ]實際要啟動的工作線程數 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是 當前線程 ID 是 Thread | 任務 ID 是
上面坦白來只算是基本功夫 貼出來還真見笑了 還有更為復雜的功能
lishixin/Article/program/Java/gj/201311/27443
Ⅷ java中怎麼用多個線程同時對一個文件讀取,最終將文件內容保存到一個位元組數組中去呢
多線程讀取文件在一塊硬碟上沒用,瓶頸在硬碟I/O,而不在CPU和內存。讀取文件時,CPU不用復雜的計算工作,只是數據傳輸而已,多線程反而造成磁頭來回移動,效率不高。如果是兩塊以上的硬碟,可以用不同的線程訪問不同的硬碟,效率比單線程要高
而且多線程操作同一文件除了效率還會有多線程問題,多個線程同時往數組里存數據還會有線程安全問題,如果不同步處理讀取的文件就是錯誤的。
如果讀取的話只能設置每個線程各自讀取偏 移量
讀取文件大小(比如大小是200K)。 2,啟動5個線程,第一個線程讀到40,第二個線程跳過40在讀到80,總之得合理安排好各個線程讀取的大小。這樣才能不重復讀取。大數據處理框架maprece原理和此類似