当前位置: 首页 > news >正文

爬虫为什么需要多线程

多线程爬虫是一种同时运行多个线程来提高爬取速度的爬虫方式。通过将大量的工作分配给不同的线程,可以减少爬虫的运行时间,提高效率。不过需要注意的是,在爬取过程中需要合理的管理线程数,以避免对被爬取的网站造成过大的负荷。

一、线程基础

1、继承Thread方式的线程

当需要再此启动一个线程时,需要再创建对象,不能重复使用。

2、推荐的创建线程方式:继承Runnalbe,使用Thread类

1.5之前就这两种
callable 第三种
可以有返回值 call()
可以抛出异常
支持泛型返回值
需要借助FutureTask, 如获取返回值的时候

class MyThread implements Callable{public Object call() throws Exception{....return null;}
}MyThread thread = new MyThread();
FutureTask f = new FutureTask(thread);
new Thread(f).start();
new Thread(f).start(); // 反复执行不会执行,需要定义新的task
try{Object ret = f.get();// get()为返回值,会阻塞主线程执行
}catch(InterruptedException){}catch(Execution e){}

在这里插入图片描述

线程池 第四种方式

提高速度,降低资源消耗
便于线程管理:核心池大小,最大线程数,没任务多长时间终止

//Executors 工具类
//ExecutorService 接口
ExecutorService service = Executors.newFixedThreadPool(10);
ThreadPoolExecutor executor = (ThreadPoolExecutor)service;
executor.setxxx() //设置参数
service.execute(Runnable);
service.submit(Callable);
service.shutdown();

b

在这里插入图片描述

4、线程分类

守护线程,用户线程

守护线程服务用户线程

thread.setDaemon(true) //设置为守护线程

最简单程序main主线程与gc回收线程

若没有用户线程jvm则结束

5、线程生命周期

NEW : 创建对象
RUNNABLE :运行 start
BLOCKED:阻塞 sleep,join,等待同步锁,wait,suspend:过时方法
WAITING:wait()
TIMED-WAITING:wait(time)
TERMINATED:stop,exception,run结束
阻塞—》就绪:sleep,join结束获取同步锁,notify,resume:过时方法

6、注意

wait:阻塞,会释放锁,必须在synchronized内
sleep:阻塞,不会释放锁,任何时候可以
wait,notify,notifyall,必须在同步方法快内,方法内,不能使用lock,他们调用时是锁对象.wait,要注意 此时syn(锁对象),两个所对象必须相同

二、线程同步

sync

与wait搭配,notify搭配,若与Lock搭配会造成异常

多用while,不用if

同步代码块,synchronized 自动锁

要求所有相乘同一把锁 synchronized(obj) obj是同一个对象,或同一个类

同步方法:当方法内容全部需要同步时

非静态方法锁即时this 需要注意

静态方法时,锁时当前类本身

Lock :接口 1.5之后

condition

能够手动开启同步,结束同步,手动锁,指定睡眠,指定唤醒

实现类

ReentrantLock:功能与synchronized,可重入锁

ReentrantReadWriteLock.ReadLock,有读锁的线程可以共享该方法,几乎相当于没加锁

ReentrantReadWriteLock.WriteLock,其他线程不共享该方法

ReentrantLock lock = new ReentrantLock();
final Condition flag1=lock.newCondition();
final Condition flag2=lock.newCondition();
try{lock.lock();flag1.await();...
}finally{lock.unlock();
}
flag2.singal();

三、线程通信

定制化通信:

/* 例:
* 切菜
* 炒菜
* 上菜
* 同时10道菜
*/
// 这里就不能用sync,需要定制化通信(唤醒睡眠的线程)
// 顺序:线程 操作 资源类
CookingLockcondation flag1,flag2,flag3cut()cooking()gaving()
Cookingnew thread(()->{for(int i=0;i<5;i++)cooking.cut();}).start()new thread(()->{for(int i=0;i<5;i++)cooking.cooking();}).start()new thread(()->{for(int i=0;i<5;i++)cooking.giving();}).start()

lambda表达式
接口可写静态方法实现,
普通方法实现,加default 关键字即可

四、JUC工具类

数据库中读写一般不是同步的

JUC中读写都是同步的,即读写同步,因为JVM线程必须加锁,否则不安全,比数据库严格

ReentraReadWriteLock:读写锁,写程序优先

CountDownLatch:计数器

CountDown count = new CountDown(10);
count.await();  // 到此方法时会判断count里面的数值,为0时继续主线程,适用于秒杀业务

CyclicBarrier:循环栅栏,多个线程处于同一状态时,才继续CyclicBarrier任务。

CyclicBarrier = cyc = new CyclicBarrier(7,任务)for (int i=0;i<7;i++)new Thread(){()->{xxxxxcyc.await();    }}

Semaphere:信号灯

Sempahere s= new Semaphere(3);for (int i=0;i<7;i++)new Thread(){()->{s.acquire();// 资源不够时会阻塞xxxxs.release();// 表示释放了资源}}
http://www.lryc.cn/news/61421.html

相关文章:

  • 下一代智能座舱风口下,“超级”Tier 1强势崛起
  • 第 三 章 UML 类图
  • java版工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单
  • 内网穿透实现在外远程连接RabbitMQ服务
  • 抖音数字人主播app
  • 亚马逊平台使用API接口通过关键字搜索商品
  • 《花雕学AI》用ChatGPT创造猫娘角色:人工智能角色扮演聊天对话的风险与对策
  • 软件测试常规测试过程模型——V模型与X模型
  • feign-starter
  • FVM初启,Filecoin生态爆发着力点在哪?
  • 对比度亮度调整与通道分离合并
  • Java终止线程
  • Qt的Qss用法
  • 数塔dp -A
  • Spring MVC 接收 json 和返回 json (14)
  • 注释和关键字
  • 第一次参加CSDN周赛,这体验很难说···
  • 8.DRF组件之认证、权限
  • 初识Tkinter弹窗
  • 设计模式之责任链模式(C++)
  • 音游判定原理详解——从触摸屏幕到判定音符【Project SEKAI攻略】
  • 【论文阅读】Self-Paced Boost Learning for Classification
  • 通过CSIG—走进合合信息探讨生成式AI及文档图像处理的前景和价值
  • 流程图拖拽视觉编程--概述
  • 深度学习中的卷积神经网络
  • vue3的介绍和两种创建方式(cli和vite)
  • camunda工作流user task如何使用
  • 三元运算符
  • Vue3 Element-plus el-menu无限级菜单组件封装
  • ( “树” 之 BST) 669. 修剪二叉搜索树 ——【Leetcode每日一题】