为什么需要线程池 在生产环境中,我们不能无限制的创建线程,主要原因如下: 线程创建与销毁的代价并不低; 如果可运行的线程数量多于可用处理器的数量,有些线程将会闲置,大量闲置的线程会消耗系统资源(内存)并给垃圾收集器带来压力; 大量线程竞争CPU也会造成不小的性能开销。 Executor框架 Executor框架在Java 5中被引入,其内部使用了线程池机制。它在java.util.cocurrent包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。 Executor框架包括:线程池,Executor,Executors,ExecutorService等(Callable与Future本篇不进行讨论)。 Executor接口 我们先来了解一下其中的Executor接口: public interface Executor { void execute(Runnable command); } Executor接口的定义非常简单,但它却为灵活 继续阅读 >>


董恒毅 18/09/13 21:38:05
关于Java线程的状态网上的说法不一,有的说是6种状态,有的说是5中状态,索性就查看了一下Java源码。Thread类里面有一个枚举类,如下: public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; } 这个枚举类里面有6种类型,所以Java中的线程有6种状态。 关于各种状态的简单说明: NEW(初始):线程被创建后尚未启动。 RUNNABLE(运行):包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程可能正在运行,也可能正在等待系统资源,如等待CPU为它分配时间片。 BLOCKED(阻塞):线程阻塞于锁。 WAITING(等待):线程需要等待其他线程做出一些特定动作(通知或中断)。 TIME_WAITING(超时等待):该状态不同于WAITING,它可以在指定的时间内自行返回。 TERMINATED(终止):该线 继续阅读 >>


李猛 18/08/15 08:19:50
synchronized 同步方法 方法内的变量线程安全,实例变量非线程安全。调用关键字synchronized声明的方法一定是排队运行的,如果不是共享资源,那么根本就没有同步的需要。 关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当做锁。对于多线程访问同一对象,哪个对象先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁Lock,其他线程就只能等待;但是如果多个线程访问多个对象,则JVM会创建多个锁。 A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法;但B线程如果在这时调用object对象中的synchronized类型的方法需要等待,也就是同步。 脏读是指在读取实例变量时,此值已经被其他线程更改过了。对于实例变量的getValue和setValue方法都要是同步的才能保证不出现脏读。 关键字synchronized拥有锁重入的功能,也就是在使用synchr 继续阅读 >>


李猛 18/08/06 19:22:51
在需要频繁开线程时,创建和销毁线程会话费大量时间,为了提高效率,我们可以在任务开始前,先创建一定数量的线程。这样在接收到任务时,就可以直接使用线程池中处于wait状态的线程,在任务结束后线程回到wait状态,等待新任务的到来,这就避免了线程的创建与销毁,从而提高程序执行效率。 所需数据 需要存储有多少线程( int thread_number ) 需要开辟对应的数组,存储线程号( pthread_t *threads ) 需要一个任务队列来存储未执行的任务,便于线程竞争任务并执行( task_queue ) 需要一个flag来标记线程池是否结束,该标记可以在线程池结束后唤醒所有处于等待线程的线程,让它们可以正常退出(其中,所有线程处于脱离(detach)状态) 互斥锁与条件变量,用于避免在获取与添加任务时发生错误(同步与互斥) 运行流程 执行ThreadPool的构造函数,初始化有关数据,进行线程的创建,并将线程进行脱离(使线程在运行完后可以自动回收) 创建的线程会去执行工作线程, 继续阅读 >>


王良 18/07/28 10:35:57
使用多线程 单线程同步,CPU利用率低;而线程异步,运行效率高。 1. 实现 Runnable 接口 class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } } PrimeRun p = new PrimeRun(143); new Thread(p).start(); Runnable只是一个接口,它里面只有一个run()方法,没有start()方法,可以使用Thread类来启动。由此可见Runnable接 继续阅读 >>


李猛 18/07/26 10:55:43
java多线程 作者:sunshine__me 发表于 2018/05/14 23:11:41 原文链接 https://blog.csdn.net/sunshine__me/article/details/80316815 阅读:37 继续阅读 >>


潘璐 18/05/14 23:11:41
新建一个专门用于 EventLoop 的线程 实现:启动一个线程,在其中运行 EventLoop::loop() 功能:运行Evenloop 知识点 条件变量使用:当多个线程对同一个变量进行操作时使用条件变量对其进行保护,条件变量同互斥锁一同起作用。 代码及分析: EventLoopThread.h // Copyright 2010, Shuo Chen. All rights reserved. // http://code.google.com/p/muduo/ // // Use of this source code is governed by a BSD-style license // that can be found in the License file. // Author: Shuo Chen (chenshuo at chenshuo dot com) #include <muduo/net/EventLoop 继续阅读 >>


楚东方 18/03/11 21:35:14
为什么会出现线程池?   思考线程池问题时,我总是会和数据库连接池联想到一起,我个人觉得它们两者的核心思想有很大的相像之处,它们都是利用了一种"池化"的思想,目的都是为了减少连接的创建和销毁.  在多线程开发中,会因为线程数量多,而且很多时侯,每个线程仅仅执行一小段时间就会结束,所以我们需要频繁的创建线程,创建线程也是会消耗系统资源的,当需求很大时,有可能导致系统负载过重而直接崩溃掉.所以,我们就想要实现线程执行完后不用销毁,同时该线程还可以去执行其他任务,因此就出现了线程池。线程池?  什么是线程池呢?通俗易懂的说法--线程池实际上就是线程的池子,基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了很多未死亡的线程,池中线程执行调度由池管理器来处理。当有线程任务时,任务提交到线程池后,就会从线程池中直接寻找空闲的线程为之服务,执行完成后将线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。   在线程池的编程模式下,任务是提交给整个线程池,而不是直接交给某个线程,线程池 继续阅读 >>


董孟愿 18/03/06 21:20:24
源码地址:多线程爬虫–抓取淘宝商品详情页URL 项目地址中包含了一份README,因此对于项目的介绍省去部分内容。这篇博客,主要讲述项目的构建思路以及实现细节。 项目概述及成果 首先将本项目使用到技术罗列出来: MySQL数据库进行数据持久化及对宕机情况的发生做简单的处理 Redis数据库做IP代理池及部分已抓取任务的缓存 自制IP代理池 使用多线程执行任务(同步块,读写锁,等待与通知机制,线程优先级) HttpClient与Jsoup的使用 序列化与反序列化 布隆过滤器 之后会对其中使用到的技术进行详细的解释。 本项目如README中所述,还有许多不完善的地方,但IP代理池与任务抓取线程之间的调度与协作基本已无问题。也就是说,在此项目的框架上,如果你想修改其中代码用作其他抓取任务,也是完全可以的。我抓取到的数据所保存的源文件也放在GitHub的README上供大家免费浏览与下载(近90000的商品ID)。 整体思路 首 继续阅读 >>


董恒毅 18/03/02 22:35:30
线程的创建创建线程具体来说有三种方式,详细内容如下文.继承Thread类详细步骤:1.定义Thread类的子类,并重写该类的run()方法,run()方法被称为线程执行体.2.创建Thread子类的实例,即创建线程对象.3.调用线程对象的start()方法启动该线程.代码示例:/** * Created by dongmengyuan on 18-2-21. */ public class FirstThread extends Thread { //i是FirstThread的实例属性,不是局部变量 private int i; //重写run()方法,run()方法的方法体是线程执行体 public void run() { for( ; i < 100; i++) { //当线程使用继承Thread类时,直接使用this就可以获取当前线程 //Thread对象的getName()返回当前线程 继续阅读 >>


董孟愿 18/02/22 12:45:53