1.队列的概念

谈到多线程先讲下队列的概念,之后的多线程学习会用到此类知识。

队列分为:阻塞式队列(有界)、非阻塞式队列(无界),遵循着先进先出、后进后出的原则。
阻塞队列与非阻塞队列区别:
1.非阻塞式队列超出队列总数会丢失。
2.阻塞式队列超出总数会进入等待(等待时间=设置超时时间)。
3.获取队列方面:非阻塞式队列,如果为空返回null。阻塞式队列,如果为空也会进入等待。
非阻塞式队列ConcurrentLinkedDeque

 //非阻塞式队列 无界(可以声明无限个队列)
public static void test1(){ ConcurrentLinkedDeque<Object> objects = new ConcurrentLinkedDeque<>();
objects.offer("java001");
objects.offer("java002"); System.out.println("队列总数:"+objects.size()); //建议:获取队列之后删除
System.out.println("获取队列但不删除:"+objects.peek());
System.out.println("获取队列但不删除,队列总数:"+objects.size());
System.out.println("获取队列删除:"+objects.poll()); //非阻塞式队列,如果为空返回null
System.out.println(objects.poll());
System.out.println(objects.poll());
System.out.println(objects.poll());
System.out.println("获取队列删除,队列总数:"+objects.size());
}


阻塞式队列ArrayBlockingQueue

 //阻塞式队列
public static void test2() throws InterruptedException { long startTime=System.currentTimeMillis();
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
arrayBlockingQueue.offer("A001",3, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A002",3, TimeUnit.SECONDS); //阻塞式队列超出总数等待(等待时间=设置超时时间)
arrayBlockingQueue.offer("A003",3, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A004",1, TimeUnit.SECONDS);
arrayBlockingQueue.offer("A005",1, TimeUnit.SECONDS); System.out.println("队列总数:"+arrayBlockingQueue.size());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
System.out.println(arrayBlockingQueue.poll());
//阻塞式队列,如果为空也会等待。
System.out.println(arrayBlockingQueue.poll(1, TimeUnit.SECONDS));
System.out.println("队列剩余总数:"+arrayBlockingQueue.size()); System.out.println("耗时:"+ (System.currentTimeMillis() - startTime)/1000 +"秒"); }

2.线程池


线程池好处:
1.降低资源 => 重复利用机制 (降低创建线程和销毁线程)
2.提高响应效率 => 当任务到达时,任务可以不需要等待去创建线程就可以执行
3.方便管理 => 无限创建线程消耗资源、降低系统稳定性。使用线程池可以统一分配、调优、监控。
线程与任务的区别:
可以把线程理解成一个工作人员。而任务就是这个工作人员干的活。比如,餐厅的工作人员在为顾客传菜,传菜就是个任务。 Java中线程就是Thread类或其子类的一个实例。
也就是说你不必关注线程对象是用哪种方法创建的。在此基础上,线程所执行的代码,即run方法中的代码所实现的处理逻辑,
比如读取数据库中的一条记录,就是一个任务。因此,所谓任务是一个相对的概念。一个任务可以是读取数据库中的一条记录,
也可以是FTP传输一批文件,FTP传输一个文件……

 //创建线程四种方式:
//1.可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
//2.定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
//3.可定时线程池,支持定时及周期性任务执行。
//4.单例线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
public static void test1() { //1.可缓存、定时、定长、单例
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
} } public static void test2() { //2.可定长线程,核心线程5个,最多创建5个线程 (只会创建5个线程,其他线程共享这5个线程)
ExecutorService executorService = Executors.newFixedThreadPool(5);
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
}
} public static void test3() { long l = System.currentTimeMillis();
//3.可定时线程 =>核心线程数3 (延迟三秒执行)
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
for (int i = 0; i <10 ; i++) { final int i1 = i;
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
System.out.println("耗时:"+ (System.currentTimeMillis() -l)/1000 +"秒" );
}
},3, TimeUnit.SECONDS);
} } public static void test4() { //4.单例线程 =>核心线程数1 最大线程数1
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i <10 ; i++) {
final int i1 = i;
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+",i:"+ i1);
}
});
}
}

 

Java线程池实现原理之自定义线程池(一)的更多相关文章

  1. 线程池的原理以及实现线程池的类ExecutorService中方法的使用

    1.线程池:线程池就是就像一个容器,而这个容器就是用来存放线程的,且有固定的容量. 如果没有线程池,当需要一个线程来执行任务时就需要创建一个线程,我们设创建线程的时间为t1,执行线程的时间为t2,销毁 ...

  2. JDBC连接池原理、自定义连接池代码实现

    首先自己实现一个简单的连接池: 数据准备: CREATE DATABASE mybase; USE mybase; CREATE TABLE users( uid INT PRIMARY KEY AU ...

  3. 【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】

    一.动态代理的作用 使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射 优点:灵活 缺点:由于其本质是反射,所以执行速度相对要慢一些 二.数据库连接池设计思想 1.为什么要使 ...

  4. Java 多线程 自定义线程辅助

    之前的文章我介绍了C#版本的多线程和自定义线程处理器. 接下来我们来看看Java版本的呢 java 的线程和C#的线程有点区别,java的线程没有是否是后台线程一说,具体原因是java的线程是jvm的 ...

  5. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  6. Executors提供的四种线程池和自定义线程池

    JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...

  7. 一个自定义线程池的小Demo

    在项目中如果是web请求时候,IIS会自动分配一个线程来进行处理,如果很多个应用程序共享公用一个IIS的时候,线程分配可能会出现一个问题(当然也是我的需求造成的) 之前在做项目的时候,有一个需求,就是 ...

  8. 自定义线程池的名称(ThreadPoolExecutor)

    目的:有时候为了快速定位出现错误的位置,在采用线程池时我们需要自定义线程池的名称. 1.创建ThreadFactory(ThreadPoolExecutor默认采用的是DefaultThreadFac ...

  9. c# 多线程系列二 自定义线程执行器

    看了第一篇文章,多线程系列,看到了在线程执行任务队列有了一定的了解~! 那么今天我来讲讲,怎么样构建通用的自定义线程概念! 线程执行任务,肯定要有目标,但是如果写死了,那么一个线程处理执行职能按照思路 ...

随机推荐

  1. Prometheus监控elasticsearch集群(以elasticsearch-6.4.2版本为例)

    部署elasticsearch集群,配置文件可"浓缩"为以下: cluster.name: es_cluster node.name: node1 path.data: /app/ ...

  2. 如果固定电脑ip地址

    打开网络和共享中心 点击详细信息,即可看到IP地址.子网掩码.默认网关.DNS服务器信息 点击本WLAN状态->属性 找到Internet 协议版本 4(TCP/IPv4) 用鼠标左键单击两下 ...

  3. 洛谷P3369 普通平衡树

    刚学平衡树,分别用了Splay和fhq-treap交了一遍. 这是Splay的板子,貌似比较短? Splay #include <iostream> #include <cstdio ...

  4. 模型评估【PR|ROC|AUC】

    这里主要讲的是对分类模型的评估. 1.准确率(Accuracy) 准确率的定义是:[分类正确的样本] / [总样本个数],其中分类正确的样本是不分正负样本的 优点:简单粗暴 缺点:当正负样本分布不均衡 ...

  5. Linux性能优化实战:系统的swap变高(08)

    一.Swap 原理 前面提到,Swap 说白了就是把一块磁盘空间或者一个本地文件(以下讲解以磁盘为例),当成内存来使用.它包括换出和换入两个过程 1.所谓换出 就是把进程暂时不用的内存数据存储到磁盘中 ...

  6. Mybatis-PageHelper

    pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  7. python GUI 之 tkinter

    写一个 登陆窗口来学习 tkinter ,还剩下一些问题 代码暂时如下 import tkinter as tk import webbrowser import pickle from tkinte ...

  8. SQL Server 跨服务器操作

    Ø  简介 在工作中编写 SQL 时经常会遇到跨库或跨服务器操作,比如查询时,通过 A 服务器的某张表关联 B 服务器某张表,进行连接查询.或者从另一台服务器中的数据,对当前数据库中的数据进行 CRU ...

  9. 《尚学堂_史上最易懂的设计模式视频》--章节5 动态代理-JDK6自带的编译器

    所有的设计模式中最难的一个 ==组合和聚合是有很大区别的 组合和聚合是有很大区别的,这个区别不是在形式上,而是在本质上: 比如A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的对象 ...

  10. 连接远程MySQL数据库项目启动时,不报错但是卡住不继续启动的,

    连接远程MySQL数据库项目启动时,不报错但是卡住不继续启动的, 2018-03-12 17:08:52.532DEBUG[localhost-startStop-1]o.s.beans.factor ...