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() {
@
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多線程處理大批文件
線程數量一般是個估算值。這個要憑經驗來判定。
判定規則如下:
如果您能保證您的線程程序不會因為等待任何I/O事件產生等待(比如等待網路、等待資料庫、等待磁碟),那麼應創建CPU進程個數個線程數。
如果您的線程程序I/O等待時間和執行時間大致相等,應創建CPU進程數x2個線程數。
③ 求多線程讀取一個文件,然後寫到另外一個文件中的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)+"毫秒");
}
}
④ java大數據 多線程寫文件
1、採用public static的變數存儲這一數值,每個線程都往這一共有靜態變數里寫入已復制大內小。 2、採用Callable方式實現多線程,容將結果作為返回值返回到主線程。這一方法只能在所有子線程都完成之後才能通過future獲取。
⑤ Java如何實現多線程傳輸文件,就像迅雷下載一樣,開十多個線程分段傳送位元組流
程序分Server和Client
伺服器端打開偵聽的埠,一有客戶端連接就創建兩個新的線程來負責這個連接
一個負責客戶端發送的信息(ClientMsgCollectThread 類),
另一個負責通過該Socket發送數據(ServerMsgSendThread )
Server.java代碼如下:
/*
* 創建日期 2009-3-7
*
* TODO 要更改此生成的文件的模板,請轉至
* 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
*/
package faue.MutiUser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 伺服器端
*
* @author Faue
*/
public class Server extends ServerSocket {
private static final int SERVER_PORT = 10000;
/**
* 構造方法,用於實現連接的監聽
*
* @throws IOException
*/
public Server() throws IOException {
super(SERVER_PORT);
try {
while (true) {
Socket socket = super.accept();
new Thread(new ClientMsgCollectThread(socket), "getAndShow"
+ socket.getPort()).start();
new Thread(new ServerMsgSendThread(socket), "send"
+ socket.getPort()).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
new Server();
}
/**
* 該類用於創建接收客戶端發來的信息並顯示的線程
*
* @author Faue
* @version 1.0.0
*/
class ClientMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/**
* 得到Socket的輸入流
*
* @param s
* @throws IOException
*/
public ClientMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
.getInputStream(), "GBK"));
}
public void run() {
try {
while (!client.isClosed()) {
inputStringBuffer.delete(0, inputStringBuffer.length());
inputStringBuffer.append(in.readLine());
System.out.println(getMsg(inputStringBuffer.toString()));
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
}
}
/**
* 構造顯示的字元串
*
* @param line
* @return
*/
private String getMsg(String line) {
return client.toString() + " says:" + line;
}
}
/**
* 該類用於創建發送數據的線程
*
* @author Faue
* @version 1.0.0
*/
class ServerMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/**
* 得到鍵盤的輸入流
*
* @param s
* @throws IOException
*/
public ServerMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(client.getOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(System.in));
}
public void run() {
try {
while (!client.isClosed()) {
outputStringBuffer.delete(0, outputStringBuffer.length());
outputStringBuffer.append(keyboardInput.readLine());
out.println(outputStringBuffer.toString());
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
}
}
}
}
客戶端:
實現基於IP地址的連接,連接後也創建兩個線程來實現信息的發送和接收
/*
* 創建日期 2009-3-7
*
*/
package faue.MutiUser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* 客戶端
*
* @author Faue
*/
public class Client {
private Socket mySocket;
/**
* 創建線程的構造方法
*
* @param IP
* @throws IOException
*/
public Client(String IP) throws IOException {
try {
mySocket = new Socket(IP, 10000);
new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"
+ mySocket.getPort()).start();
new Thread(new ClientMsgSendThread(mySocket), "send"
+ mySocket.getPort()).start();
} catch (IOException e) {
//e.printStackTrace();
System.out.println("Server.IP:" + IP
+ " port:10000 can not be Connected");
}
}
public static void main(String[] args) throws IOException {
try {
new Client(args[0]);
} catch (Exception e) {
System.out.println("輸入的IP地址錯誤");
}
}
/**
* 該類用於創建接收服務端發來的信息並顯示的線程
*
* @author Faue
* @version 1.0.0
*/
class ServerMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/**
* 得到Socket的輸入流
*
* @param s
* @throws IOException
*/
public ServerMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
.getInputStream(), "GBK"));
}
public void run() {
try {
while (!client.isClosed()) {
inputStringBuffer.delete(0, inputStringBuffer.length());
inputStringBuffer.append(in.readLine());
System.out.println(getMsg(inputStringBuffer.toString()));
}
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
System.exit(0);
}
}
/**
* 構造輸入字元串
*
* @param line
* @return
*/
private String getMsg(String line) {
return client.toString() + " says:" + line;
}
}
/**
* 該類用於創建發送數據的線程
*
* @author Faue
* @version 1.0.0
*/
class ClientMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/**
* 得到鍵盤的輸入流
*
* @param s
* @throws IOException
*/
public ClientMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(client.getOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(System.in));
}
public void run() {
try {
while (!client.isClosed()) {
outputStringBuffer.delete(0, outputStringBuffer.length());
outputStringBuffer.append(keyboardInput.readLine());
out.println(outputStringBuffer.toString());
}
out.println("--- See you, bye! ---");
} catch (IOException e) {
//e.printStackTrace();
System.out.println(client.toString() + " is closed!");
System.exit(0);
}
}
}
}
如果對您有幫助,請記得採納為滿意答案,謝謝!祝您生活愉快!
vaela
⑥ java 多線程問題 真的提高了效率嗎
你鑽了牛角尖了。不要從cpu耗時上看,並行一般是為了任務處理。並發是為了資源共享和資源的充分利用。二者可比性不大。
你所說的cpu一般是指,分時系統中的cpu,比如linux,其中一個用戶A的一個線程要30個小時完成,另外一個用戶B的線程需要1000個小時。而且其中需要用戶不斷響應,如果沒有並發,B用戶先開始,A用戶需要等待1030小時。如果使用並發,A用戶可能四五十個小時就搞定了。如果A和B都比較有money,一人買一台,沒有這個問題的。這就是並行。資源充足怎麼著都行,資源不足只能找折中方案了。
如果你覺得這是進程的概念,java里一樣的。你做過web開發吧。你肯定不想每個請求都分一個伺服器吧。開發一個網頁,一台電腦同時有上千個人訪問你的tomcat,一般不會有問題。瀏覽也順暢。這就是並發的作用。這種情況如果使用單線程。一千個人有999個人等著看你的網頁,而第一個人操作的時候cpu大部分時間是空閑的。怎麼利用起來就成了個問題。這也叫效率。
如果確實必須要考慮問題處理的效率問題。你訪問資料庫的時候用過線程池嗎?是不是能縮短訪問資料庫所耗費的時間。所以效率高不高不能只看cpu用了多少時間。你可以再考慮考慮,不用多線程,你怎麼設計一個單線程程序,同時監聽鍵盤和麥克風的信息錄入?
其實計算機底層是有天然的非同步特性的。這個東西就是中斷。有些耗時的io操作,什麼時候處理完是可以不用管的。剩下的無關線程就可以自由自在的進行了。這樣效率是不是也高了。
單cpu一般也是多核的。
⑦ java多線程同時讀取一個文件,這個方法可行嗎
不可行。
多線程能夠提高效率是因為現在的cpu普遍是多核cpu, 多條線程可以在版多個內核中權同時執行來提高計算效率。但是計算機磁碟的磁頭只有一個,即使多條線程去讀也並不能提高讀取效率,反而因為多線程的上下文切換問題會耗時更久。
⑧ 如何解決:多線程和單線程拷貝文件那個效率高
看場景;
效率的瓶頸不在代碼的時候,比如用的最多的io操作,
下載羨液器,下載伺服器每個介面就給你500k的速度,那多線程相當於500*n,本地網路明汪最大2m每秒,兄槐物可以開3~5個線程自然快;
復制器,windows操作系統復制文件很慢,因為負責復制的api防止系統卡死每個線程就給你那點速度,如果用java寫個多線程io流復制,速度快8倍左右;
這樣的場合有個特點,速度或者說效率的關鍵不是java的處理能力,而是介面限製成了瓶頸;
舉個反例,如果對一個集合進行遍歷,列印value,使用多線程明顯比單線程效率低;因為時間過多的消耗在了創建線程,銷毀線程上,執行的有用代碼和單線程沒區別,效率不如單線程;
⑨ java中怎麼用多個線程同時對一個文件讀取,最終將文件內容保存到一個位元組數組中去呢
多線程復讀取文件在一塊硬碟上沒制用,瓶頸在硬碟I/O,而不在CPU和內存。讀取文件時,CPU不用復雜的計算工作,只是數據傳輸而已,多線程反而造成磁頭來回移動,效率不高。如果是兩塊以上的硬碟,可以用不同的線程訪問不同的硬碟,效率比單線程要高
而且多線程操作同一文件除了效率還會有多線程問題,多個線程同時往數組里存數據還會有線程安全問題,如果不同步處理讀取的文件就是錯誤的。
如果讀取的話只能設置每個線程各自讀取偏 移量
讀取文件大小(比如大小是200K)。 2,啟動5個線程,第一個線程讀到40,第二個線程跳過40在讀到80,總之得合理安排好各個線程讀取的大小。這樣才能不重復讀取。大數據處理框架maprece原理和此類似