Java并发系列「4」-- Thread 线程池 (关于博客之星的小秘密)

记录在程序走的每一步___auth:huf


大家好呀;我是老胡,又来学习并发咯;

最近刚好开启 年度博客之星的卷神之战;

今天我们就来说一下 我们为什么要使用线程;

线程能达到什么样的一个效果;

使用场景又是什么? 是不是特别应景.


关于年度博客之星

====================================================================

我是一个上班族 也不是职业博主; 最近是因为一个项目结束。 空档期。 参与到了这场比赛中;

非常有意义。 结识了非常多 技术能力非常强的技术博主。

交流技术。交流对策。

我知道 在第二轮专家评审可能会处于劣势。因为卷不过职业博主。

乐在参与~

我的数据与 爬虫无关 这里特此声明一下;

(期间各路大神各显神通,csdn作为一个技术类的大站, 这种刷票这种情况发生不足为奇。)

在Java体系中 :

有一个工具 叫做selenium; 还有一个event 。。。只有想不到没有做不到

我开始寻找 起点 以及 终点

第一 所有参赛博主 https://bbs.csdn.net/topics/603959602

尾部的603959602 统计参赛者的具体数量。

最后得出结论 从603956005 到 603962830 得出 6825的一个人数;

其中在顺着网址的同时 会出现 学校生消防平安常识.docx下载 类似于

最终参赛人数 应该在 6400 6500 左右的人数;

处理方式也很简单。 直接 title.startsWith(“2021年「博客之星」”) 进行精准预判就行

(这样可以快速进入到目标篇章;)

(可以获取title然后把页面跳转出去-这样可以有效刷到所有的帖子;)

然后通过class 获取到span 得到List 后 直接取最后一个span 进行点击;

点击的时候 可能会出现异常 这时候可以利用 executeScript(“arguments[0].click();”,webElement);

然后通过class 获取到 input框 然后出发input框的click事件 这时候

只需要把评论放进去 然后获取到提交按钮 进行触发即可;

-------------------------虽然以上方式 会 很麻烦; 但是看起来像是人为的。

可以通过 算法 将数字打乱;然后无序点击。 都是可以做到的。


如果想快速获取分数。 就得获取到相对应的接口;然后直接对接口进行请求;效率是最高的;

如果这时候加上多线程。 是完全可以在十分钟内点击完整个网站的评论;以及 打分。

为了保证接口承受压力以及稳定性。 还可以让线程进行睡眠。 保证其发送请求的速度。以及频率。

据我所知C站是有两位大神做出这样程序 。造出了核弹 并且使用了核弹


经 本人同意:

小小明 明佬 是一名非常优秀,资深的程序员。 使用的方式

并且写了一篇文章 链接地址给大家放这:

https://blog.csdn.net/as604049322/article/details/122345251

核弹级别


还有一位神秘的大神发现。 还有一种方式可以直接更改分数。 可以一票轰5万分。

后台没有做校验。传多少是多少。并且 可以是负数。接口没有加密。

黑洞级别(至今未使用)


卷神之战已经结束。因为有这样的 核推动力

配合 :https://blog.csdn.net/wenaicoo/article/details/122225908

侥幸的拿到了 29000 分。 甚至找过队友 进行配合刷通宵

在这里插入图片描述


我们的一个Http请求 是一个单线程的请求; 我们来画一张图;

在这里插入图片描述

我们的请求:

可以是登入 可以是调取第三方接口 可以是业务逻辑

是我们所有实现的开始:

实际业务逻辑:

《现在已经海选完毕,思路进行公布》

我参加了年度博客之星

!如果说 ! 我要做一个爬虫;


每一次 只能开一个页面 给一个用户评论;

需要做的事 是get出url 然后找到评论区 最后黏贴评论

提交


这时候 我开启了十条线程。每条线程 做相同的事情;

可以在短时间内刷完整个CSDN年度博客之星的博主评论区;


在 没有规则下 放飞自我; 我去做这件事

首先

可以进一步去优化整个流程;

因为获取整个页面麻烦。那么就做一个事;就是获取请求接口;直接怼接口上;

如果用Java实现 该怎么实现? 每一次请求怼一次接口? 这样合理嘛?

以下画图来说明以下整个流程:

在这里插入图片描述

老胡当时的想法;

在这里插入图片描述

然后想到效率问题;老胡的想法得到优化:实际可以:

在这里插入图片描述

OK . 分析出来了链路 我们就开干…

哈哈哈哈 通过以上例子

我们就可以清晰知道。

我们可以通过多线程干什么。

跑题了… 我们还是回归到整体 继续分析Thread 线程池;

以下是我们开启线程的

package com.huf;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

/**

  • auth:huf

*/

public class ThreadTest {

public static void main(String[] args) throws InterruptedException {

//记录开始时间

Long startTime = System.currentTimeMillis();

//随机数对象

final Random random = new Random();

//存储生成出来的随机数

final List list = new ArrayList<>();

//循环十万次

for (int i = 0; i < 100000; i++) {

//开启线程

Thread thread = new Thread(() -> {

list.add(random.nextInt());

});

//线程立即执行

thread.start();

//线程关联 等所有线程执行完 然后再执行下一段代码

thread.join();

}

System.out.println(“执行时间:” + (System.currentTimeMillis()-startTime));

System.out.println(“容器大小:” + list.size());

}

}

执行结果为:

在这里插入图片描述

居然需要十一秒;

我们反思;为什么 这样做需要十一秒?

我们分析一波:

使用这种方式。 我们一共创建了 100001条线程; 一条主线程;

1:线程数量多; 不代表速度越快;

2:线程需要消耗资源,如果大量创建线程就需要大量资源;

3:创建完线程后又销毁;没有复用。下一次需要用又得创建;

基于上面的缺点; 实际上可以通过线程池来做 也进入到了我们本篇文章的正题:

ThreadPoolExecutor

我写了一个例子 来说明 使用线程池跟不适用线程池究竟有什么差别

package com.huf;

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

/**

  • @Description TODO

  • @Auth: Huf

  • @Date: 2022/1/7

**/

public class ThreadTest2 {

public static void main(String[] args) throws InterruptedException {

//记录开始时间

Long startTime = System.currentTimeMillis();

//随机数对象

Random random = new Random();

//存储生成出来的随机数

List list = new ArrayList();

//Executors 创建出单例线程池;

ExecutorService executorService = Executors.newSingleThreadExecutor();

for (int i = 0; i < 100000; i++) {

//开启线程

executorService.execute(()->{

list.add(random.nextInt());

});

}

executorService.shutdown();

executorService.awaitTermination(1, TimeUnit.DAYS);

System.out.println(“执行时间:” + (System.currentTimeMillis()-startTime));

System.out.println(“容器大小:” + list.size());

}

}

执行结果:

在这里插入图片描述

一百多倍…

为什么相差了一百多倍?

这里简单解释一下: 因为这里只开启了2个线程 ; 放到第五章线程池源码篇去详细说明;


Java Executors自带线程池 的简单使用

=====================================================================================

我们来看一组数据

最后

面试题文档来啦,内容很多,485页!

由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

1111道Java工程师必问面试题

MyBatis 27题 + ZooKeeper 25题 + Dubbo 30题:

Elasticsearch 24 题 +Memcached + Redis 40题:

Spring 26 题+ 微服务 27题+ Linux 45题:

Java面试题合集:

最后

面试题文档来啦,内容很多,485页!

由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

1111道Java工程师必问面试题

[外链图片转存中…(img-mjRkvU6u-1719270655112)]

MyBatis 27题 + ZooKeeper 25题 + Dubbo 30题:

[外链图片转存中…(img-brVPkTyd-1719270655112)]

Elasticsearch 24 题 +Memcached + Redis 40题:

[外链图片转存中…(img-eZleESr8-1719270655113)]

Spring 26 题+ 微服务 27题+ Linux 45题:

[外链图片转存中…(img-Syu9xVyM-1719270655113)]

Java面试题合集:

[外链图片转存中…(img-GAhRZkBD-1719270655114)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值