java进阶-多线程学习笔记
多线程学习笔记
1.什么是线程
操作系统中 打开一个程序就是一个进程
一个进程可以创建多个线程
现在系统中 系统调度的最小单元是线程
2.多线程有什么用?
- 发挥多核CPU的优势
- 如果使用多线程 将计算逻辑分配到多个处理器核心上 会减少程序处理时间
- 防止阻塞
- 一个业务内部需要多个业务配合完成 如果是单线程 就会发生执行一件后再执行另一件,如果是多线程 可以多个业务逻辑 并发执行 快速响应用户请求 缩短响应时间
- 便于建模
- 比如有一个大任务 特别复杂 可以分解成多个小任务
分别建立程序模型,并通过多线程分别运行这几个任务 那就简单很多了。
3.什么是线程的优先级
在多线程运行的过程中,操作系统会分出一个个的时间片,当线程的时间片用完了就会发生线程调度,并等待下次分配。线程分配到多少时间片也就决定了线程使用处理器资源的多少,线程的优先级就是决定线程需要多少或者分配多少处理器资源的线程属性
通过priority控制 线程创建时 setPriority() 修改优先级 1-10 针对频繁阻塞的线程 设置较高的优先级 偏重计算的 设置较低的优先级 确保处理器不会被独占
4.线程有几种状态
1.new 初始化状态 线程被创建 但还没有调用start方法
2.runnable 运行状态 就绪和运行两种状态统称位运行中
3.blocked 阻塞状态 表示线程阻塞与锁
4.waiting 等待状态 表示线程进入了等待状态 当前线程需要等待其他线程做出一些特定的动作 通知或者中断
5.time_waiting 超时等待状态 指定时间自行返回
6.terminated 终止状态 表示 线程一件执行完毕
5.什么是Deamon线程
在程序中后台调度的线程 被用作完成一些支持性工作
如果java中已经没有了非deamon线程 则虚拟机就会退出
6.启动和终止线程
1.集成Thread类
2. 实现Runnable接口
3.Callable和Future创建线程
实现接口的方式比继承类的方式更灵活
启动 用start()方法
含义:当前线程同步告知java虚拟机,只要线程规划器空闲,应立即启动调用start()方法的线程。
线程中断:
调用线程的interrupt()方法进行中断
通过isIntterrupt()判断是否被中断
调用Thread.interrupted()对当前的中断标识进行复位。如果线程已经被终结 即使被中断过 在调用isIntterrupt()时也是返回false
7.过期的suspend() resume() stop()方法 暂停 恢复 停止
原因 suspend()调用后线程不会释放已经占有的资源(锁) 容易发生死锁。
被以后的等待/通知等机制来代替
8.安全的终止线程
通过设置标志位
通过调用interrupt()
private volatile boolea on = true;
public void run(){
while(on && !Thread.currentThread().isInterruped()){
i++;
}
}
public void cancel(){
on =false;
}
通过调用cancel()来终止线程
通过次方式终止时 线程会有时间去清理资源
9.线程间通信
每个线程都有自己的栈空间
如果每个线程孤立运行 没有什么价值
1.对变量 加volatile关键字
告知程序 任何程序对该变量的访问都要从共享内存中去获取,对它的任何修改都要同步刷新回共享内存中。保证了它对所有线程的可见性。
如果过多的使用volatile 回降低程序执行的效率。
2.通过关键字 synchronized 修饰方法或者同步快
确保多个线程在同一时刻 只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性。
10.等待和通知
wait() 调用该方法的线程进入waiting状态 只有等待另外线程的通知或被中断才会返回,调用次方法会释放对象锁。
wait(long) 超时等待一段时间,参数 毫秒 如果没有通知就超时返回。
wait(long int)对超时时间更加细粒度控制 可以达到纳秒。
notify() 通知一个在对象上等待的线程,使其从wait()方法返回,返回的前提是该线程获取了对象的锁。
notifyAll() 通知所有等待在该对象上的线程。
经典范式
等待方:
- 获取对象锁
- 如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件
- 条件满足 则执行对应逻辑
synchronized(对象){
while(条件不足){
对象.wait();
}
对应的处理逻辑
}
通知方:
1.获得对象的锁。
2.改变条件
3.通知所有等待在对象上的线程
synchronized(对象){
改变条件
对象.notifyAll();
}
11. Thread.join() 当前线程等待thread线程终结之后才从thread.join()返回。
与上面的等待通知机制一个原理
12.ThreadLocal的使用
线程变量 以ThreadLocal对象为键 任意对象为值 存储的存储结构
一个线程可以根据一个ThreadLocal对象擦好像到绑定在这个线程的值
13.等待超时模式
等待时间
synchronized(对象){
将来时间=当前时间+等待时间
while(条件不足&&等待时间>0){
对象.wait(等待时间);
等待时间=将来时间-当前时间
}
对应的处理逻辑
14.线程安全的概念
当多个线程访问某个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)是安全的。
锁
15.lock接口
锁是用来控制多个线程访问共享资源的方式 ,一般来说 一个锁能防止多个线程同事访问共享资源。排它锁。
lock具备synchronized关键字不具备的主要特征:
尝试非阻塞地获取锁
能被中断地获取锁 能够响应中断 当获取到锁的线程被中断时 中断已超将被抛出 并释放锁
超时获取锁 在指定的时间之前获取锁 如果时间到了 无法获取则返回
lock基本操作
lock() 获取锁
lockInterruptibly()可中断获取锁 就是获取锁后 可以响应中断。
tryLock() 尝试非阻塞的获取锁 获取到则返回true 否则返回false
tryLock(time,unit)超时获取锁 1在设置时间内获得锁 2 在设置时间内被中断 3 超时 结束 返回false
unlock() 释放锁
newCondition() 获取等待通知组件 该组件和当前的锁绑定 当前线程只有获得锁 才能调用该组件的wait()方法 而调用后 当前线程将锁释放掉。
多个线程多个锁:多个线程每个线程都可以拿到自己指定的锁 获得锁后 再执行synchronized方法体的内容 在静态方法上加锁 等于在这个类上加锁
原子性 一致性 隔离性 永久性
java进阶-多线程学习笔记的更多相关文章
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- 《深入理解Java虚拟机》学习笔记
<深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...
- JavaEE精英进阶课学习笔记《博学谷》
JavaEE精英进阶课学习笔记<博学谷> 第1章 亿可控系统分析与设计 学习目标 了解物联网应用领域及发展现状 能够说出亿可控的核心功能 能够画出亿可控的系统架构图 能够完成亿可控环境的准 ...
- Java:NIO 学习笔记-3
Java:NIO 学习笔记-3 根据 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 3. JAVA NIO 深入剖析 在讲解利用 NIO 实现通信架构之前,我们需要先来了解一下 NI ...
- JAVA GUI编程学习笔记目录
2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...
- Java安全防御学习笔记V1.0
Java安全防御学习笔记V1.0http://www.docin.com/p-766808938.html
随机推荐
- Python 入门demo第一篇
#-*- coding: UTF-8 -*- 2.7版本对中文的要求 import uuid import socket def get_mac_address(): mac=uuid.UUID(in ...
- 一个可变布局列表,有9种布局item大小,每个item可拖拽切换位置
代码地址如下:http://www.demodashi.com/demo/11271.html 一.准备工作 准备一台安卓设备手机,4.4以上版本 本例子实现,一个可变布局列表,有9种布局item大小 ...
- jenkins部署前端node项目实例
Jenkins 分发文件用到rsync命令 在 /etc/passwd中 修改 jenkins 为 /bin/bash jenkins:x:494:494:Jenkins Automation S ...
- ip地址库选择
目前市面上常用的ip地址库,有以下几种 1,新浪的api接口(限制未知)http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js& ...
- LAMP架构二
安装PHP7 1.查看php配置文件信息(phpinfo),php有两个配置文件开发环境和生产环境 [root@localhost php-5.6.30]# /usr/local/php/bin/ph ...
- Vim进阶指南
常用按键说明 按键 解释 移动光标 n+(Space) 向右移动n个字符 n+(Enter) 向下移动n行 nG 移动到第n行 gg 移动到第一行 G 移动到最后一行 0或Home键(Mac使用fn+ ...
- self.navigationItem.titleView 不居中显示的问题
自定义一个AUIView, AUIView * v=[AUIView new]; self.navigationItem.titleView = v; 在AUIView类内重写 setFrame - ...
- mysql general log 查看mysql 运行历史
我们有时候须要查看mysql的运行历史,比方我们做sql优化的时候,起码要知道运行的sql是什么.框架通常会帮我们拼装sql,所以在程序中不一定能够打印出sql,这个时候就须要mysql的genera ...
- Oracle Restart能够用来给Oracle GoldenGate 做 High Availability 使用么?
Oracle Restart能够用来给Oracle GoldenGate 做 High Availability 使用么? 来源于: Can Oracle Restart be used with ...
- c#各类型转byte[]或转回
var tmp = BitConverter.ToInt32(new byte[]{...}); var bytes = BitConverter.GetBytes(tmp); 而String转byt ...