【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<String> fL = getData(fN,"([\\u4e00-\\u9fa5]{4})(,|。)",1);ArrayList<String> bL = getData(bN,"([\\u4e00-\\u9fa5]{2})(、|。)",1);ArrayList<String> gL = getData(gN,"([\\u4e00-\\u9fa5]{2})( )",1);System.out.println(fL);}private static ArrayList<String> getData(String str, String regex,int index) throws IOException {ArrayList<String> 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<String> 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<String> mL = new ArrayList<>();for (String s : bL) {if(!mL.contains(s)){mL.add(s);}}//女名:去重ArrayList<String> wL = new ArrayList<>();for (String s : gL) {if(!wL.contains(s)){wL.add(s);}}System.out.println(wL);
}
3.组合名字
HashSet<String> 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<String> familyNameTempList = ReUtil.findAll("([\\u4e00-\\u9fa5]{4})(,|。)",familNameStr,1);List<String> boyNameTempList = ReUtil.findAll("([\\u4e00-\\u9fa5]{2})(、|。)",boyNameStr,1);List<String> 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)多线程的三种实现方式
- 继承Thread类的方式进行实现
- 实现Run那别了接口的方式进行实现
- 利用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 {@Overridepublic 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{@Overridepublic 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<Integer> ft = new FutureTask(mc);Thread t1 = new Thread(ft);t1.start();System.out.println(ft.get());}
}
public class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 0; i < 100; i++) {sum += i;}return sum;}
}
对比
4.1)多线程中的常用成员方法
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 {@Overridepublic 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() {}@Overridepublic 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());//默认优先级是5System.out.println(t2.getPriority());t1.setPriority(1);//最高10 最低1t2.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 {@Overridepublic 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);}}
}