Thread and File
-
作用:
为什么要引入线程?其实就是为了提高cpu利用率,也就是效率。
-
基本概念:
什么是进程?什么是线程?简单来说,进程好比一个APP,而线程就是其底下的任务,而任务是可以有多个的,也就是多线程,当然进程也可以多个,但这里不讨论。线程不能独立的存在,它必须是进程的一部分。就像main()方法,main()就是一个主线程 / 进程,其底下分出的线程任务就是子线程。
多线程与单线程就好比说,我们来比100公里谁跑的快,单线程就是一个人从头跑到尾,而多线程则是多个人合作跑,那效率肯定是多线程高啦,但是多线程要处理好协作的问题,不然你说那几个吊毛万一在争论这段路谁来跑,谁也不让睡,那效率肯定大打折扣,甚至可能低于单线程。
-
线程的生命周期
新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
创建线程
-
Java 提供了三种创建线程的方法:
- 通过实现 Runnable 接口;
- 通过继承 Thread 类本身;
- 通过 Callable 和 Future 创建线程。
-
通过 Callable 和 Future 创建线程(有返回值)
创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
-
调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
-
实例
/* 有10个文件,每个文件里有10000000个随机生成的数,每个数的大小都在1~1000之间,写一个程序,依次读取每个文件,统计每个文件里每个数字出现的次数,再汇总. */ public class Parallel { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) throws ExecutionException, InterruptedException, IOException { System.out.println("----Program starting----"); Date date1 = new Date(); int taskSize = 4; //create a Thread pool with taskSize tasks ExecutorService pool = Executors.newFixedThreadPool(taskSize); ArrayList<Future<Map<String, Integer>>> list = new ArrayList<>(); String filepath = "src\\Test1\\data\\"; File file = new File(filepath); File[] filelist = file.listFiles(); for (int i = 0; i < filelist.length; i++) { Callable c = new MyCallable(filelist[i]); // get Future with return value FutureTask f = (FutureTask) pool.submit(c); list.add(f); } // block Thread until done pool.shutdown(); try { pool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { e.printStackTrace(); } //count map Map<String, Integer> map = new HashMap<>(); for (int i = 1; i <= list.get(0).get().size(); i++) { int sum=0; for (int j = 0; j <list.size(); j++) sum += list.get(j).get().get(i+""); if (!map.containsKey(i+"")) map.put(i+"", sum); else map.put(i+"", map.get(""+i)+sum); } //write to r.txt write_r(map); Date date2 = new Date(); System.out.println("Program running time:"+ (date2.getTime() - date1.getTime()) + "ms"); //about 7200ms } //write to r.txt public static void write_r(Map<String, Integer> map) throws IOException { File writename = new File("src\\Test1\\result\\r.txt"); writename.createNewFile(); BufferedWriter out = new BufferedWriter(new FileWriter(writename)); for (int j = 1; j <= map.size(); j++) { out.write(j+","+map.get(j+"")+"\n"); } out.flush(); // flush file out.close(); // close file } } class MyCallable implements Callable<Object> { private File file; private Map<String, Integer> map = new HashMap<>(); public MyCallable(File file) { this.file = file; } // deal files @SuppressWarnings("resource") public static void deal_Files(File file,Map<String, Integer> map) throws IOException { InputStreamReader reader = new InputStreamReader(new FileInputStream(file)); BufferedReader br = new BufferedReader(reader); String line = ""; while ((line = br.readLine()) != null) { if (!map.containsKey(line)) map.put(line, 1); else map.put(line, map.get(line)+1); } } public Object call() throws Exception { deal_Files(file, map); return map; } }
-
再补充下 Java对文件的处理,#具体代码#
上一篇: 关于表达爱意的句子
下一篇: python3 scrapy模拟登陆豆瓣
推荐阅读
-
Linux中文件描述符fd与文件指针FILE*互相转换实例解析
-
使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:
-
用file标签实现多图文件上传预览
-
mvc file控件无刷新异步上传操作源码
-
Python多线程编程(三):threading.Thread类的重要函数和方法
-
C#多线程之Thread中Thread.IsAlive属性用法分析
-
JAVA多线程Thread和Runnable的实现
-
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
-
成功解决SyntaxError: Non-UTF-8 code starting with xc0 in file but no encoding declared; see http://p
-
Android WebView 不支持 H5 input type="file" 解决方法