本份随记主要为狂神老师的Java多线程教学的学习笔记,记载了视频中一些有关基础概念以及部分代码示例。随机分为1-3共三份,知识点记录的不是很深入,以后的学习过程中随时补充。

1 有关基础概念

1.1 核心概念

  1. 线程就是独立的执行路径
  2. 程序运行时,即使没有自己创建线程,后台也会由多个线程(主线程、gc线程)
  3. main()称之为主线程,为系统的入口,用于执行整个程序
  4. 一个进程中,若开辟多个线程,线程的运行由调度器安排调度,调度器与操作系统紧密相关,先后顺序不能被人为干预。
  5. 对同一份资源操作时,会存在资源抢夺问题,需加入并发控制
  6. 线程会带来额外的开销(cpu调度时间,并发控制开销)
  7. 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致(队列和锁)。

1.2 程序、进程、线程

  1. 程序(静态概念):程序是指令和数据的有序集合,本身没有任何运行的含义
  2. 进程(动态概念):程序的一次执行过程,是系统资源分配的单位
  3. 线程:CPU调度和分派的基本单位。(进程中可包含至少一个的若干线程)
  4. 进程 vs 线程:

    同一进程中的线程使用相同的地址空间,而不同的进程则不会。这允许线程读写公共共享和数据结构和变量,也增加了线程之间的通信。然而,进程间通信(即IPC)是非常困难的,并且需要耗费大量资源。

1.3 并发、并行

  1. 并行:两个或多个事务在同一时刻发生。

    实际多线程为并行执行:多个cpu(多核)共同执行线程。
  2. 并发:两个或多个事务在同一时间间隔内发生。

    模拟多线程为并发执行:在一个cpu情况下同一时间点只能执行一个线程,但切换很快。

2 线程创建

2.1 Thread class(继承Thread类)

  1. 自定义线程类继承Thread类
  2. 子类重写父类的run方法,编写程序执行体
  3. 分配并启动子类的实例(创建线程对象,调用start方法启动线程)

程序示例:

点击查看代码
// 1.创建子类继承自Thread类
public class CreateThread extends Thread{ //2.重写run方法
@Override
public void run() {
for(int i = 0; i < 5; i++){
System.out.println("Run.No." + i);
}
}
public static void main(String[] args){
//3.创建一个线程对象
CreateThread createThread1 = new CreateThread();
//3.调用start方法开启线程
createThread1.start();
for (int i = 0; i < 5; i++) {
System.out.println("No." + i);
} }
}

注: 线程开启不一定立即执行,由CPU调度执行,线程执行顺序不是由定义顺序决定的。

2.2 Runnable接口的实现

  1. 定义MyRunnable类实现Runnable接口
  2. 实现run方法,编写程序执行体
  3. 创建线程对象(代理),调用start方法启动线程。

    new Thread(implementRunnable1).start();

程序示例:

点击查看代码
// 1.实现runnable接口
public class ImplementRunnable implements Runnable{ //2.重写run方法
@Override
public void run() {
for(int i = 0; i < 200; i++){
System.out.println("Run.No." + i);
}
}
public static void main(String[] args){
//3.1 创建一个接口实现类对象
ImplementRunnable implementRunnable1 = new ImplementRunnable();
//3.2 创建线程对象,通过线程对象开启线程(代理)
Thread thread = new Thread(implementRunnable1);
// 3.3调用线程start方法
thread.start();
// 3-归并
new Thread(implementRunnable1).start();
for (int i = 0; i < 5; i++) {
System.out.println("No." + i);
} }
}

2.3 Thread与Runnable的对比

2.3.1 继承Thread类:

  1. 创建方法:子类继承Thread类具备多线程能力
  2. 启动线程方法:子类对象.start()
  3. 不建议使用:避免单继承局限性

2.3.2 实现Runnable接口:

  1. 实现接口Runnable具有多线程能力
  2. 启动线程方法:new Thread(传入目标对象).start()
  3. 推荐使用:避免了单继承局限性,灵活方便,方便同一对象被多个线程使用。

2.4 Callable接口(了解)

  1. 实现Callable接口,需返回值类型
  2. 重写call方法,需抛出异常
  3. 创建目标对象
  4. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
  5. 提交执行:Future<Boolean> result1 = ser.submit(t1);
  6. 获取结果:boolean r1 = result1.get();
  7. 关闭服务:ser.shutdownNow();

优缺点分析:

  1. 可以定义返回值
  2. 可以抛出异常
  3. 实现方式较为复杂

3 静态代理

示例:婚庆公司结婚模型(你去结婚,婚庆公司帮你结婚)

内容:

  1. 结婚接口Marry
  2. 你You:参与结婚的角色
  3. 婚庆公司WeddingCompany: 代理角色,帮你完成结婚这件事
  4. 比较Thread,婚庆公司~Thread, You~要调用的线程对象(实现runnable接口的类),thread代替接口实现类去做一些事情

    new WeddingCompany(new You("Mike")).HappyMarry();

    new Thread(() -> System.out.println("I love you!")).start();

模式总结:

  1. 真实对象和代理对象都要实现同一个接口
  2. 代理对象要代理真实角色
  3. 优势
    1. 代理对象可以做很多真实对象不愿做或无法做的事
    2. 真实对象专注做自己的事

4 线程状态

线程可以处于以下状态之一:

  1. NEW: 尚未启动的线程处于此状态。
  2. RUNNABLE:在Java虚拟机中执行的线程处于此状态。
  3. BLOCKED:被阻塞等待监视器锁定的线程处于此状态。
  4. WAITING:正在等待另一个线程执行特定动作的线程处于此状态。
  5. TIMED_WAITING:正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
  6. TERMINATED:已退出的线程处于此状态。

一个线程可以在给定时间点处于一个状态。 这些状态是不反映任何操作系统线程状态的虚拟机状态。


与此有关的一些线程方法

4.1 线程停止

  1. 不推荐JDK提供的stop,destroy方法[已过时 @Deprecated]
  2. 推荐线程自行停止(利用次数,不建议死循环)
  3. 建议使用标志位进行终止变量,当flag=false则终止线程运行。

4.2 线程休眠(sleep)

  1. sleep(时间)指定当前线程阻塞的毫秒
  2. sleep存在异常InterruptedException
  3. sleep时间打倒后线程进入就绪状态
  4. sleep可以模拟网络延时,倒计时等
  5. 每个对象都有一个锁,sleep不会释放锁

4.3 线程礼让(yield)

概念: 让当前正在执行的线程暂停,但不阻塞(将线程从运行状态转为就绪状态)。

礼让为让CPU重新调度,因此礼让成功与否取决于CPU。

4.4 线程强制执行(join)

Join合并线程,待此线程执行完成后再执行其他线程,其他线程阻塞。

类似于VIP插队

4.5 线程状态观测(Thread.State)

线程状态State为Thread类中的枚举类型:

public static enum Thread.State extends Enum<Thread.State>

获取线程状态的方法:

Thread.State state = thread.getState(); System.out.println(state);

4.6 线程优先级

  • Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定该调度哪个线程来执行。

范围:线程优先级用数字表示[1, 10]

Thread.MIN_PRIORITY = 1; Thtead.MAX_PRIORITY = 10

改变/获取线程优先级:

getPriority(), setPriority(int xxx)

注:先设置优先级再启动;优先级低只是意味着获得调度的概率低。

4.7 守护线程(daemon)

  1. 线程分为用户线程和守护线程
  2. 虚拟机必须确保用户线程执行完毕(main)
  3. 虚拟机不用等待守护线程执行完毕(gc)
  4. 守护线程:后台记录操作日志,监控内存,垃圾回收等

Java多线程-1(3)的更多相关文章

  1. 40个Java多线程问题总结

    前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...

  2. Java多线程基础知识篇

    这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...

  3. Java多线程系列--“JUC锁”03之 公平锁(一)

    概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...

  4. Java多线程系列--“JUC锁”04之 公平锁(二)

    概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...

  5. Java多线程--让主线程等待子线程执行完毕

    使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...

  6. Java多线程 2 线程的生命周期和状态控制

    一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...

  7. java 多线程 1 线程 进程

    Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报  分类: javaSE综合知识点(14)  版权声明:本文为博主原创文章,未经博 ...

  8. 一起阅读《Java多线程编程核心技术》

    目录 第一章 Java多线程技能 (待续...)

  9. 第一章 Java多线程技能

    1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...

  10. java从基础知识(十)java多线程(下)

    首先介绍可见性.原子性.有序性.重排序这几个概念 原子性:即一个操作或多个操作要么全部执行并且执行的过程不会被任何因素打断,要么都不执行. 可见性:一个线程对共享变量值的修改,能够及时地被其它线程看到 ...

随机推荐

  1. Crash course statistics

    Crash course statistics 01什么是统计学 描述性统计(Descriptive statistics) 推理统计可以得出之外的,基于"样本"的推论统计学来估计 ...

  2. rancherUI添加configmap

    1.创建configmap 2.部署pod,挂载配置文件(通过卷的形式引用)

  3. PXE高效批量装机

    目录 一.PXE概述 二.PXE的优点 三.搭建PXE的前提 四.搭建PXE远程安装服务器 4.1.安装并启用TFTP服务 4.2.安装dhcp服务 4.3.准备linux内核.初始化镜像文件 4.3 ...

  4. 【XSS-labs】level 6-10

    Level 6 查看源码:对URL中的传参进行了HTML实体化转义,搜索框中的值对 src\onxxxxx\data\href进行了限制. 采用大小写绕过,在搜索框输入payload,注意闭合inpu ...

  5. windows10右键我的电脑,点击管理,提示该文件没有与之关联的应用来执行该操作,请安装应用,若已经安装应用,请在默认应用设置页面中创建关联……

    方法一 1.按WIN+R 调出运行对话框,然后输入bai gpedit.msc 回车:2.展开"计du算机配置"zhi-"Windows设置"-"安全 ...

  6. C#多线程---Mutex类实现线程同步

    一.例子 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 ...

  7. Linux命令:ps -ef |grep java

    一.ps -ef |grep java 查看包含"java"的所有进程 二.涉及命令详解 ps命令将某个进程显示出来(是LINUX下最常用的也是非常强大的进程查看命令) grep命 ...

  8. 搭建zabbix监控系统详解

    搭建zabbix监控系统详解 文:warren   博文大纲:一.前言 二.zabbix监控架构三.搭建Zabbix监控服务器四.搭建过程中遇到有些服务无法正常启动的解决办法 一.前言 : 要想实时的 ...

  9. 使用Operator State方式

    使用 operator state的方式有以下几种: 方式一: stateful function(RichFunction) 实现 CheckpointFunction 接口 必须实现两个方法:Vo ...

  10. 日常shell练习

    2021-07-19 1.echo的使用 1.1 echo -n 表示不换行输出 # echo输出会自动换行,换行输出两个1 echo 1 echo 1 # 不换行输出,不换行输出两个1 echo - ...