java学习-多线程的创建

细雨轻风      2022-05-12     780

关键词:

多线程查找文件内容

遍历所有文件,当遍历到文件名是.java结尾的时候,创建一个线程去查找这个文件的内容(是否包含“Magic”字符串),不必等待这个线程结束,继续遍历下一个文件。

  1 package multiplethread;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.FileNotFoundException;
  6 import java.io.FileReader;
  7 import java.io.IOException;
  8 
  9 public class searchFileInDirectory {
 10     // 实现Runnable接口方式的多线程
 11     public static void funcThread1(String path) {
 12         File f = new File(path);
 13         if (f.exists()) {
 14             File[] fs = f.listFiles();
 15             for (File x : fs) {
 16                 if (x.isDirectory())
 17                     funcThread1(x.getAbsolutePath());
 18                 if (x.isFile() && x.getName().contains(".java")) {
 19                     new Thread(new searchInFile(x)).start();
 20                 }
 21             }
 22         }
 23     }
 24 
 25     public static void checkFile(File x) {
 26         Thread t = new Thread() {
 27             public void run() {
 28                 try (BufferedReader br = new BufferedReader(new FileReader(x));) {
 29                     while (true) {
 30                         String line = br.readLine();
 31                         if (line == null)
 32                             break;
 33                         if (line.contains("Magic")) {
 34                             System.out.printf("找到目标字符串\"Magic\",在文件%s%n", x.getAbsoluteFile());
                    break;// 只要文件含有content,不管出现多少次,只打印一次文件地址
35 } 36 } 37 } catch (IOException e) { 38 // TODO Auto-generated catch block 39 e.printStackTrace(); 40 } 41 } 42 43 }; 44 t.start(); 45 } 46 47 // 匿名类的方式的多线程 48 public static void funcThread2(String path) { 49 File f = new File(path); 50 if (f.exists()) { 51 File[] fs = f.listFiles(); 52 for (int i = 0; i < fs.length; i++) { 53 File x = fs[i]; 54 if (x.isDirectory()) { 55 funcThread2(x.getAbsolutePath()); 56 } 57 if (x.isFile() && x.getName().contains(".java")) { 58 checkFile(x); // 理论上直接写到这里可以,但是为了美观便于阅读,就单独写到checkFile()中 59 } 60 } 61 62 } 63 } 64 65 // 单线程 66 public static void funcNoThread(String path) { 67 File f = new File(path); 68 if (f.exists()) { 69 File[] fs = f.listFiles(); 70 for (File x : fs) { 71 if (x.isDirectory()) 72 funcNoThread(x.getAbsolutePath()); 73 if (x.isFile() && x.getName().contains(".java")) { 74 try (BufferedReader br = new BufferedReader(new FileReader(x));) { 75 while (true) { 76 String line = br.readLine(); 77 if (line == null) 78 break; 79 if (line.contains("Magic")) { 80 System.out.printf("找到目标字符串\"Magic\",在文件%s%n", x.getAbsoluteFile()); 81 } 82 } 83 } catch (IOException e) { 84 // TODO Auto-generated catch block 85 e.printStackTrace(); 86 } 87 88 } 89 } 90 } 91 } 92 93 public static void main(String[] args) { 94 String path = "F:\\project\\javastudy"; 95 long st1 = System.currentTimeMillis(); 96 funcThread1(path); 97 long et1 = System.currentTimeMillis(); 98 System.out.printf("多线程Thread1下花费时间:%d ms", et1 - st1); 99 100 long st2 = System.currentTimeMillis(); 101 funcThread2(path); 102 long et2 = System.currentTimeMillis(); 103 System.out.printf("多线程Thread2下花费时间:%d ms", et2 - st2); 104 105 long st3 = System.currentTimeMillis(); 106 funcNoThread(path); 107 long et3 = System.currentTimeMillis(); 108 System.out.printf("单线程下花费时间:%d ms", et3 - st3); 109 } 110 }

效果图:

 ...

 

 ...

 

 由于文件数量较少,多线程与单线程所耗时间基本一致。

 练习-英雄充能

英雄有可以放一个技能叫做: 波动拳-a du gen。
每隔一秒钟,可以发一次,但是只能连续发3次。
发完3次之后,需要充能5秒钟,充满,再继续发。

 1 package multiplethread;
 2 
 3 import charactor.Hero;
 4 
 5 public class ThreadTest2 {
 6 
 7     public static void main(String[] args) {
 8         Thread t1 = new Thread() {
 9             private int cnt = 0;
10 
11             public void run() {
12                 while (true) {
13                     if ((++cnt) % 4 != 0) {
14                         System.out.printf("波动拳第%d发\n", cnt);
15                         try {
16                             Thread.sleep(1000);
17                         } catch (InterruptedException e) {
18                             // TODO Auto-generated catch block
19                             e.printStackTrace();
20                         }
21                     } else {
22                         cnt = 0;
23                         try {
24                             System.out.println("开始为时5秒的充能");
25                             Thread.sleep(5000);
26                         } catch (InterruptedException e) {
27                             // TODO Auto-generated catch block
28                             e.printStackTrace();
29                         }
30                     }
31                 }
32             }
33         };
34         t1.start();
35 
36     }
37 }

效果图:

 

练习-破解密码

1. 生成一个长度是3的随机字符串,把这个字符串当作密码

2. 创建一个破解线程,使用穷举法,匹配这个密码

3. 创建一个日志线程,打印都用过哪些字符串去匹配,这个日志线程设计为守护线程:setDaemon(true)

提示: 破解线程把穷举法生成的可能密码放在一个容器中,日志线程不断的从这个容器中拿出可能密码,并打印出来。 如果发现容器是空的,就休息1秒,如果发现不是空的,就不停的取出,并打印。

 1 package multiplethread;
 2 
 3 import java.util.LinkedList;
 4 import java.util.Random;
 5 
 6 public class Test2 {
 7     public static String getRandomString(int length) {
 8         String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 9         Random random = new Random();
10         StringBuffer sb = new StringBuffer();
11         for (int i = 0; i < length; i++) {
12             int number = random.nextInt(62);
13             sb.append(str.charAt(number));
14         }
15         return sb.toString();
16     }
17 
18     public static void main(String[] args) throws InterruptedException {
19         String pwd = getRandomString(3);
20         LinkedList<String> pwdList = new LinkedList<>();
21         System.out.println("pwd :" + pwd);
22         Thread t1 = new Thread() {
23             String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
24             int n = str.length();
25             char[] cs = new char[3];
26 
27             public void run() {
28                 ok: for (int i = 0; i < n; i++) {
29                     for (int j = 0; j < n; j++) {
30                         for (int k = 0; k < n; k++) {
31                             cs[0] = str.charAt(i);
32                             cs[1] = str.charAt(j);
33                             cs[2] = str.charAt(k);
34                             String guess = new String(cs);
35                             pwdList.add(guess);
36                             // t1和t2这两个线程并发执行,但是t2由于要挨个打印,必然晚于t1结束,而t1早已经匹配到密码
37                             // 不妨令t1匹配到密码时等一等t2,等t2打印完。
38                             // 这里设置为等5秒钟(5秒钟基本能匹配成功)
39                             if (guess.equals(pwd)) {
40                                 try {
41                                     Thread.sleep(3000);
42                                 } catch (InterruptedException e) {
43                                     // TODO Auto-generated catch block
44                                     e.printStackTrace();
45                                 }
46                                 System.out.println("匹配成功!密码是:" + guess);
47                                 break ok;
48                             }
49                         }
50                     }
51                 }
52             }
53         };
54         Thread t2 = new Thread() {
55             public void run() {
56                 while (true) {
57                     String tmp = pwdList.poll();
58                     // 发现容器是空的,就休息1秒
59                     if (tmp == null) {
60                         try {
61                             Thread.sleep(1000);
62                         } catch (InterruptedException e) {
63                             // TODO Auto-generated catch block
64                             e.printStackTrace();
65                         }
66                     } else {
67                         System.out.println("可能是:" + tmp);
68                     }
69                 }
70             }
71         };
72         t2.setDaemon(true);
73         t1.start();
74         t2.start();
75     }
76 }

效果图:

 练习-多线程交互

 对同一个对象(Hero),有2个加血线程,5个扣血线程,同时运行。最大血量1000,最小血量1。

使用wait()、notify()。

其中Hero类的加血、扣血方法如下:

 1     //回血
 2         public synchronized void recover(){
 3             if(hp==1000){
 4                 try {
 5                     this.wait();    //满血不能再加血
 6                 } catch (InterruptedException e) {
 7                     // TODO Auto-generated catch block
 8                     e.printStackTrace();
 9                 }
10             }else{
11                 hp=hp+1;
12                 System.out.printf("%s 回血1点,增加血后,%s的血量是%.0f%n", name, name, hp);
13                 this.notify();        //不满血则可以扣血(自然可以加血)
14             }
15         }
16          
17         //扣血
18         public synchronized void hurt(){
19             if(hp<=1){
20                 try {
21                     this.wait();    //空血不能再扣血
22                 } catch (InterruptedException e) {
23                     // TODO Auto-generated catch block
24                     e.printStackTrace();
25                 }
26             }else{
27                 hp-=1;
28                 System.out.printf("%s 减血1点,减少血后,%s的血量是%.0f%n", name, name, hp);
29                 this.notify();        //非空血可以加血(自然可以扣血)
30             }  
31         }

多线程交互:

 1 package multiplethread;
 2 
 3 import charactor.Hero;
 4 
 5 public class Test_wait_notify {
 6     
 7     public static void main(String[] args) {
 8         final Hero gareen = new Hero();
 9         gareen.name = "盖伦";
10         gareen.hp = 616;
11         
12         Thread addHP[]=new Thread[2];
13         Thread reduceHP[]=new Thread[5];
14       //2条加血线程
15         for(int i=0;i<2;i++){
16             Thread t=new Thread(){
17                 public void run(){
18                     while(true){
19                         gareen.recover();
20                         //加血间隔 10ms
21                         try {
22                             Thread.sleep(10);
23                         } catch (InterruptedException e) {
24                             // TODO Auto-generated catch block
25                             e.printStackTrace();
26                         }
27                     }
28                 }
29             };
30             t.start();
31             addHP[i]=t;
32         }
33         //5条扣血线程
34         for(int i=0;i<5;i++){
35             Thread t=new Thread(){
36                 public void run(){
37                     while(true){
38                         gareen.hurt();
39                         //扣血间隔 10ms
40                         try {
41                             Thread.sleep(10);
42                         } catch (InterruptedException e) {
43                             // TODO Auto-generated catch block
44                             e.printStackTrace();
45                         }
46                     }
47                 }
48             };
49             t.start();
50             reduceHP[i]=t;
51         }
52         
53     }
54 }

效果图:

 

第十周java学习总结

目录第十周java学习总结学习内容代码上传截图代码链接第十周java学习总结学习内容第12章Java多线程机制主要内容Java中的线程Thread类与线程的创建线程的常用方法线程同步协调同步的线程线程联合GUI线程计时器线程重点和难点重... 查看详情

java多线程学习-一

开启多线程1,继承Thread2,重写run方法3,将要执行的代码写在run方法中4,创建Thread类的子类对象5,开启线程/***@paramargs*/publicstaticvoidmain(String[]args){MyThreadmt=newMyThread();//4,创建Thread类的子类对象mt.start();//5,开启线程for(inti=0;i<1000;i++ 查看详情

java基础学习:多线程04

java基础学习:多线程04创建线程方式1:基类继承Thread类;重写run()方法,定义线程体;主类中:创建线程对象;调用start()方法,启动线程;(线程启动并不会立即执行,由CPU调度) 案例:多线程下载图片:​/***练习thread,... 查看详情

java多线程学习

首先讲一下进程和线程的区别:  进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。  线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈... 查看详情

多线程编程学习五(线程池的创建)

一、概述NewThread的弊端如下:    a、每次NewThread新建对象性能差。    b、线程缺乏统一的管理,可能无限制的新建线程,相互之间竞争,极可能占用过多的系统资源导致死机或者OOM。   &nbs... 查看详情

多线程java多线程学习笔记|多线程基础知识(代码片段)

Java多线程学习笔记|多线程基础知识文章目录Java多线程学习笔记|多线程基础知识一.线程与进程二.Java中创建线程1.编写继承Thread的类,重写run方法2.编写实现Runnable的类,重写run方法3.其他方式的创建三.线程的生命周期四.... 查看详情

java学习第22天(关于进程的创建及使用)

多线程其实在操作系统已经深入了解过,现在就不做学习概念,其实理解线程很简单,首先进程就是一种正在内核态运行的软件,而线程就是一种轻量化的进程,和进程不同的是线程一般存在于一个进程中,共享地址空间。具体... 查看详情

java多线程学习二

//1,定义一个类实现Runnable//2,重写run方法//3,将要执行的代码写在run方法中//4,创建Runnable的子类对象//5,将其当作参数传递给Thread的构造函数//6,开启线程publicclassAppiumpage{publicstaticvoidmain(String[]args){MyRunnerablemr=newMyRunnerable();Threadt=ne 查看详情

多线程编程学习笔记

多线程编程目录线程概述线程的创建创建线程程序线程同步守护线程线程之间的相互通讯线程池和java.util.concurrent包一、概述1.相关概念进程(Process):程序(任务)执行的过程,每个进程都有自己独立的一块内存空间,一个进程中可... 查看详情

java学习多线程:线程创建线程状态线程同步线程通信全总结(代码片段)

目录1、基本概念2、线程创建2.1、继承Thread类(重点)ThreadAPI2.2、实现Runnable接口(重点)Runnable接口API以上两种方式的比较:初识并发问题——买火车票龟兔赛跑问题:img2.3、实现Callable接口(了解ÿ... 查看详情

java多线程学习(代码片段)

什么是进程进程是一个可执行的应用程序,任何进程都有一个主线程作为入口,是线程的集合什么是多线程多线程可以提高效率,我们在电脑操作的时候,开多个窗口,并不是多线程并发,是cpu在切换,只不过速度很快,我们感觉不到,多线... 查看详情

java之多线程创建方式

多线程的由来我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计?要解决上述问题,咱们得使用多进程或者多线程来解决.多线程的好处:提高程序... 查看详情

第五周作业(java多线程创建的三个方法)

  我最近在学习Java中多线程,并且觉得多线程这块在以后的Java开发中显得极为重要,就谈一下Java实现多线程的三种方式。JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实... 查看详情

java学习-7

线程线程的调度:分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。抢占式调度:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。创... 查看详情

尚硅谷_java零基础教程(多线程)--学习笔记(代码片段)

Java多线程一、基本概念1、程序、进程、线程2、单核CPU和多核CPU、并行与并发3、使用多线程的优点二、线程的创建和使用1、API中创建线程的两种方式1.1、方式一:继承Thread类1.2、方式二:实现Runnable接口1.3、Thread类的调... 查看详情

多线程学习

1、start()和run()的区别start()才是真正意义的实现了多线程,因为start会让线程处于就绪状态,不用等run运行结束就可以继续运行下面的代码,而如果直接调用run就是普通的方法调用,程序是顺序执行的2、用哪个方法创建线程好... 查看详情

java篇多线程详解(代码片段)

哈哈!经过一个阶段的学习,Java基础知识学习终于到多线程了!Java多线程以及后面互斥锁的概念都是Java基础学习的难点,所以我做了一个总结,希望对大家也有帮助! 下面开始学习Java多线程吧!目... 查看详情

java线程池学习

一、实现Java多线程的方法1、继承Thread类创建多线程Thread类本质实现了Runnable接口。启动线程为start0()方法。是个native方法。1publicclassThreadProcessextendsThread{23@Override4publicvoidrun(){5longlastTime=System.currentTimeMillis();6for(inti=0; 查看详情