> 技术文档 > 【Java学习|黑马笔记|Day21】IO流综合练习,多线程|常用成员方法,守护线程、礼让线程、插入线程

【Java学习|黑马笔记|Day21】IO流综合练习,多线程|常用成员方法,守护线程、礼让线程、插入线程


【DAY22】

欢迎大家在评论区交流讨论,一起学习共同进步🕵🏻‍♀️

文章目录

    • 【DAY22】
      • 一.综合练习
        • 1)网络爬虫
        • 2)登录注册
      • 二.多线程
        • 1)概念
        • 2)并发和并行
        • 3)多线程的三种实现方式
        • 4.1)多线程中的常用成员方法
        • 4.2)线程的优先级
        • 4.3)守护线程
        • 4.4)礼让线程
        • 4.5)插入线程
        • 5)线程的生命周期

一.综合练习

1)网络爬虫

1.爬取姓氏名字

public class T1 { public static void main(String[] args) throws IOException { String familyName = \"https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0\"; String boyName = \"http://www.haoming8.cn/baobao/10881.html\"; String girlName = \"http://www.haoming8.cn/baobao/7641.html\"; //2.爬取数据,把数据拼成字符串 String fN = webCrawler(familyName); String bN = webCrawler(boyName); String gN = webCrawler(girlName); //3.用正则表达式把符合要求的数据取出来 ArrayList fL = getData(fN,\"([\\\\u4e00-\\\\u9fa5]{4})(,|。)\",1); ArrayList bL = getData(bN,\"([\\\\u4e00-\\\\u9fa5]{2})(、|。)\",1); ArrayList gL = getData(gN,\"([\\\\u4e00-\\\\u9fa5]{2})( )\",1); System.out.println(fL); } private static ArrayList getData(String str, String regex,int index) throws IOException { ArrayList list = new ArrayList(); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); while(matcher.find()) { list.add(matcher.group(index)); } return list; } public static String webCrawler(String net) throws IOException { //1.定义StringBuilder拼接爬取到的数据 StringBuilder sb = new StringBuilder(); //2.创建一个URL对象 URL url = new URL(net); //3.链接网址 URLConnection conn = url.openConnection(); //4.读取数据 InputStreamReader isr = new InputStreamReader(conn.getInputStream()); int ch; while((ch = isr.read()) != -1) { sb.append((char)ch); } isr.close(); return sb.toString(); }}

2.处理数据

//4.处理数据 //姓氏:把四个拆开放到新的集合中 ArrayList xL = new ArrayList(); for (String str : fL) { for(int i = 0; i < str.length(); i++){ char c = str.charAt(i); xL.add(c + \"\");//把char变成字符串 } } //男名:去重 ArrayList mL = new ArrayList(); for (String s : bL) { if(!mL.contains(s)){ mL.add(s); } } //女名:去重 ArrayList wL = new ArrayList(); for (String s : gL) { if(!wL.contains(s)){ wL.add(s); } } System.out.println(wL);}

3.组合名字

HashSet bhs = new HashSet();while(true){ if(bhs.size() == Count){ break; } Collections.shuffle(fN); Collections.shuffle(bN); bhs.add(fN.get(0) + bN.get(0));}

糊涂包生成假数据

public class T1 { public static void main(String[] args) { String familyName = \"https://hanyu.baidu.com/shici/detail?pid=0b2f26d4c0ddb3ee693fdb1137ee1b0d&from=kg0\"; String boyName = \"http://www.haoming8.cn/baobao/10881.html\"; String girlName = \"http://www.haoming8.cn/baobao/7641.html\"; String familNameStr = HttpUtil.get(familyName); String boyNameStr = HttpUtil.get(boyName); String girlNameStr = HttpUtil.get(girlName); List familyNameTempList = ReUtil.findAll(\"([\\\\u4e00-\\\\u9fa5]{4})(,|。)\",familNameStr,1); List boyNameTempList = ReUtil.findAll(\"([\\\\u4e00-\\\\u9fa5]{2})(、|。)\",boyNameStr,1); List girlNameTempList = ReUtil.findAll(\"([\\\\\\\\u4e00-\\\\\\\\u9fa5]{2})( )\",girlNameStr,1); //处理数据 //生成数据 //写出数据 FileUtil.writeLines(list,\"D://\",\"UTF-8\"); }}
2)登录注册

将正确的用户名和密码存入本地的txt文件

让用户键盘输入用户名和密码比较是否正确

//username=zhangsan%password=123
public class T1 { public static void main(String[] args) throws IOException { //1.读取正确的用户名和密码 BufferedReader br = new BufferedReader(new FileReader(\"src\\\\1.txt\")); String line = br.readLine(); String[] userInfo = line.split(\"&\"); String[] arr1 = userInfo[0].split(\"=\"); String[] arr2 = userInfo[1].split(\"=\"); String rightUsername = arr1[0]; String rightPassword = arr1[1]; Scanner sc = new Scanner(System.in); System.out.println(\"请输入用户名\"); String username = sc.nextLine(); System.out.println(\"请输入密码\"); String password = sc.nextLine(); if(rightUsername.equals(username) && rightPassword.equals(password)){ System.out.println(\"登陆成功\"); }else { System.out.println(\"登录失败\"); } }}

二.多线程

1)概念

进程:每一个正在运行的软件都是一个进程,是程序的基本执行实体

线程:是操作系统能够进行运算调度的最小单位,被包含在进程中,是进程中的实际运行单位

作用:有了多线程就可以让程序同时做多件事情,提高效率

2)并发和并行

并发:在同一时刻,有多个指令在单个CPU上交替运行

并行:在同一时刻,有多条指令在多个CPU上同时进行

3)多线程的三种实现方式
  1. 继承Thread类的方式进行实现
  2. 实现Run那别了接口的方式进行实现
  3. 利用Callable接口和Future接口方式实现

法一

public class T1 { public static void main(String[] args) { //1.定义一个类继承Thread //2.重写run方法 //3.创建子类的对象启动线程 MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.setName(\"线程1\"); t2.setName(\"线程2\"); //开启线程 t1.start(); t2.start(); }}
public class MyThread extends Thread { @Override public void run() { //书写线程要执行的代码 for (int i = 0; i < 100; i++) { System.out.println(getName() + \"123\"); } }}

法二

public class T1 { public static void main(String[] args) { //1.自己定义一个类实现Runnable接口 //2.重写里面的run方法 //3.创建自己的类的对象 //4.创建一个Thread类对象 Myrun mr = new Myrun(); Thread t1 = new Thread(mr); Thread t2 = new Thread(mr); t1.setName(\"t1\"); t2.setName(\"t2\"); t1.start(); t2.start(); }}
public class Myrun implements Runnable{ @Override public void run() { //书写线程要执行的代码 for (int i = 0; i < 100; i++) { //获取当前线程的对象 Thread t = Thread.currentThread(); System.out.println(t.getName() + \"asdfg\"); } }

法三

public class T1 { public static void main(String[] args) throws ExecutionException, InterruptedException { //1.定义一个类MyCallable实现Callabe接口 //2.重写里面的call方法(有返回值) //3.创建自己的类的对象(表示多线程要执行的任务) //4.创建FutureTask的对象(作用管理多线程运行的结果) //5.创建一个Thread类对象 MyCallable mc = new MyCallable(); FutureTask ft = new FutureTask(mc); Thread t1 = new Thread(ft); t1.start(); System.out.println(ft.get()); }}
public class MyCallable implements Callable { @Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; }}

对比

【Java学习|黑马笔记|Day21】IO流综合练习,多线程|常用成员方法,守护线程、礼让线程、插入线程

4.1)多线程中的常用成员方法

【Java学习|黑马笔记|Day21】IO流综合练习,多线程|常用成员方法,守护线程、礼让线程、插入线程

public class T1 { public static void main(String[] args) { //细节:如果没有给线程设置名字,线程也有默认名字 // 格式:Thread-X X为序号,从0开始 MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.start(); t2.start(); }}///.............................................public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(getName() + \"@\" + i); } }}
public class T1 { public static void main(String[] args) { //细节:如果要给线程设置名字,可以用setName可以用构造方法 MyThread t1 = new MyThread(\"飞机\"); MyThread t2 = new MyThread(\"坦克\"); t1.start(); t2.start(); }}//......................................................public class MyThread extends Thread { public MyThread(String name) { super(name); } public MyThread() { } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(getName() + \"@\" + i); } }}
//当JVM虚拟机启动之后,会自动的启动多条线程,其中一条线程叫做,=main线程,用来调用main方法并执行里面的代码
4.2)线程的优先级

抢占式调度:随机

public class T1 { public static void main(String[] args) { MyThread t1 = new MyThread(\"飞机\"); MyThread t2 = new MyThread(\"坦克\"); System.out.println(t1.getPriority());//默认优先级是5 System.out.println(t2.getPriority()); t1.setPriority(1);//最高10 最低1 t2.setPriority(10);//优先级更高抢到CPU的概率越高 t1.start(); t2.start(); }}
4.3)守护线程
public class T1 { public static void main(String[] args) { //当非守护线程执行完毕后,守护线程就会陆续结束 MyThread t1 = new MyThread(\"飞机\"); MyThread t2 = new MyThread(\"坦克\"); //把第二个线程设置为守护线程 t2.setDaemon(true); t1.start(); t2.start(); }
4.4)礼让线程
public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(getName() + \"@\" + i); //表示出让当前CPU的执行权 Thread.yield(); } }}
4.5)插入线程
public class T1 { public static void main(String[] args) throws InterruptedException { MyThread t1 = new MyThread(\"飞机\"); t1.start(); //把t1这个线程插入到当前线程之前 //等t1线程全部执行完再执行别的 t1.join(); //执行在main线程中的 for (int i = 0; i < 10; i++) { System.out.println(\"main线程\" + i); } }}
5)线程的生命周期

【Java学习|黑马笔记|Day21】IO流综合练习,多线程|常用成员方法,守护线程、礼让线程、插入线程