【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 {
@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<Integer> ft = new FutureTask(mc);
Thread t1 = new Thread(ft);
t1.start();
System.out.println(ft.get());
}
}
public class MyCallable implements Callable<Integer> {
@Override
public 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 {
@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);
}
}
}