首先,用到的线程类有CountDownLatch。进行子线程的计数的。子线程中run最后面调用countDownLatch.countDown();方法,该子线程执行完后便减一,主线程中子线程的start后调用cDownLatch.await();方法,实现主线程等待并发子线程。
以下代码是实现多线程进行一个文件的读写,相当于复制了。目的是为实现多线程并发,虽然速度上还有点欠缺。
先是主程序代码
package com.filethread; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.CountDownLatch; public class ReadFileMain { static FileThread[] fThread; static long startTime; final static String OUT_FILE_NAME = "C:\\Users\\dandan\\Desktop\\卑鄙的我2.神偷奶爸2.DVD中字-cut.rmvb"; /** * @param args */ public static void main(String[] args) { final int DOWN_THREAD_NUM = 4; final String READ_FILE = "C:\\Users\\dandan\\Desktop\\svn\\卑鄙的我2.神偷奶爸2.DVD中字-cut.rmvb"; InputStream[] isArrInputStreams = new InputStream[DOWN_THREAD_NUM]; RandomAccessFile[] outArrAccessFiles = new RandomAccessFile[DOWN_THREAD_NUM]; try { isArrInputStreams[0] = new FileInputStream(READ_FILE); long fileLen = getFileLength(new File(READ_FILE)); System.out.println("文件的大小" + fileLen); //以输出文件名创建第一个RandomAccessFile输出流 outArrAccessFiles[0] = new RandomAccessFile(OUT_FILE_NAME, "rw"); //创建一个与文件相同大小的空文件 for (int i = 0; i < fileLen / 1024; i++) { try { outArrAccessFiles[0].write(1024); // System.out.println(i+ "------" + fileLen / 1024 + "相差:" + (fileLen / 1024 - i)); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } //每线程应该读取的字节数 long numPerthread = fileLen / DOWN_THREAD_NUM; startTime = System.currentTimeMillis(); System.out.println(new SimpleDateFormat("yy-MM-DD HH:MM:SS").format(new Date())); //整个文件整除后剩下的余数 long end = fileLen % DOWN_THREAD_NUM; fThread = new FileThread[DOWN_THREAD_NUM]; CountDownLatch cDownLatch = new CountDownLatch(DOWN_THREAD_NUM); for (int i = 0; i < DOWN_THREAD_NUM; i++) { FileThread f2 = null; //为每个线程打开一个输入流、一个RandomAccessFile对象, //让每个线程分别负责读取文件的不同部分。 if (i != 0) { isArrInputStreams[i] = new FileInputStream(READ_FILE); //以指定输出文件创建多个RandomAccessFile对象 outArrAccessFiles[i] = new RandomAccessFile(OUT_FILE_NAME, "rw"); } if (i == DOWN_THREAD_NUM - 1) { //最后一个线程读取指定numPerThred+left个字节 f2 = new FileThread(i * numPerthread, (i+1) * numPerthread + end, isArrInputStreams[i], outArrAccessFiles[i],cDownLatch); }else { //每个线程负责读取一定的numPerThred个字节 f2 = new FileThread(i * numPerthread, (i + 1) * numPerthread, isArrInputStreams[i], outArrAccessFiles[i],cDownLatch); } f2.start(); fThread[i] = f2; } /** //判断所有子线程是否执行完毕, int size = fThread.length; // while(true){ for (int i = 0; i < size;) { if (fThread[i] != null && fThread[i].getState() == Thread.State.TERMINATED) { fThread[i] = null;size--; } if(fThread[i] != null && fThread[i].getState() == Thread.State.RUNNABLE) System.out.println(fThread[i].getId() + "存活中"); if(size == 0) warrting();break; } // } */ try { cDownLatch.await(); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } warrting(); } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } public static void warrting() { System.out.println("开始读取:时间---" + ReadFileMain.startTime); long endTime = System.currentTimeMillis(); System.out.println("读取完毕:时间---" + endTime); System.out.println("耗时:" + (endTime - ReadFileMain.startTime)); System.out.println(new File(ReadFileMain.OUT_FILE_NAME).length()); System.out.println(new SimpleDateFormat("yy-MM-DD HH:MM:SS").format(new Date())); } public static long getFileLength(File file) { // long length = 0; // //获取文件的长度 // long size = file.length(); // length = size; // return length; return file.length(); } }
下面是子线程
相关推荐
Java多线程--让主线程等待所有子线程执行完毕
我就废话不多说了,还是直接看代码吧! from time import ctime import threading import time def a(): #for i in range(5): print('Program a is running... at ', ctime(),u'.线程名为:',threading.current...
Handler消息传递详解,子线程到子线程,主线程到子线程,子线程到主线程 三种消息,Looper,Handler工作机制详解 https://blog.csdn.net/shoneworn/article/details/80447651
Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程...
Unity异步线程调用主线程脚本程序,在Unity中异步线程调用主线程会报错,所以编写了一个Loom
c#子线程如何读取及设置主线程ui的值,自己录的一个小视频,方便理解,比较菜鸟的方法,请勿喷!
qt 多线程 防止主线程做循环操作导致界面假死。试过多线程的几种方法,只有这个方法可行。代码亲测可行。在子线程死循环,界面正常不死!!!
下面小编就为大家带来一篇C#子线程执行完后通知主线程的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
C#子线程刷新主线程示例源码 功能介绍: 使用线程操作 1、实时显示当前时间 2、输入加数和被加数,自动出现... 使用了多线程实现了子线程刷新主线程 ,使用委托刷新主线程。 注意: 开发环境为Visual Studio 2012
NULL 博文链接:https://dsqiu.iteye.com/blog/2028503
java 子线程通过观察者模式通知主线程
子线程更新主线程数据(再谈多线程)
多个子线程运行,当所有子线程运行完毕,监控线程退出,并且返回所有子线程取得的数据。
Unity除了一些基本的数据类型,几乎所有的API都不能在子线程中调用,如果项目中有一段很耗时操作,unity可能会出现“卡死...因此针对这个问题再加上查找了一些资料,弄出了一个小工具,可以子线程与主线程的相互访问。
C# Winfrom必须掌握的技术,主线程显示数据,子线程获取数据,这是我做项目实际用到的技术。
Java主线程等待所有子线程执行完毕在执行,其实在我们的工作中经常的用到,本篇文章就介绍了Java多线程--让主线程等待所有子线程执行完毕在执行,有需要的可以了解一下。
子线程任务发生异常,主线程事务如何回滚
本资源详细介绍了主线程和子线程之间的通信过程,通过实例讲解了参数如何传递
Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码 22 如何从子线程更新主线程数据Visual C++源代码...