Java 线程高级
1.volatile关键字:当多个线程操作共享数据时,可以保证内存中的数据可见,相较于syncronized是一种较为轻量级的同步策略,
注意:1.volatile不具有“互斥性”
2.volatile不能保证变量的"原子性"
2.i++的原子性问题:i++的操作实际上分为三个步骤”读-改-写“
int i = 10;
i = i++;//10
int temp = i;
i = i+1;
temp = i;
3.解决原子性的方式:原子变量:jdk1.5后,java.util.concurrent.atomic 包下提供了常用的原子性变量,变量的特点如下
1.volatile保证内存可见性
2.CAS(compare and swap)算法保证数据的原子性
CAS算法是硬件对于并发操作共享数据的支持
CAS包含3个操作数:
内存值V
预估值A
更新值B
当且仅当V == A 时,V = B,否则,将不做任何操作
ConcurrentHashMap采用”锁分段“级别
CountDownLatch:闭锁操作
实现Callable的方式相比于实现Runnable接口的方式区别:可以存在返回值,可以抛出异常,执行Callable的方式,需要FutureTask<>实现类的支持,用于接收运算结果,FutureTask是Future接口的实现类
解决多线程安全的三种方式
1.synchronized同步代码块
2.synchronized同步方法
3.Lock 同步锁,显示锁:需要通过lock()进行上锁,必须进行unlock()解锁,更加灵活,使用Lock等待,lock.newCondition();
生产者-消费者模式种,使用wait()和notify()实现等待唤醒机制,使用这个机制的原因是,如果不进行等待,则消费者或生产者在条件不满足的情况下,还是会去频繁进行条件判断
为了避免虚假唤醒问题(多个生产者和消费者,造成数据错乱的现象),应该把wait()始终使用在循环中,wait()方法会使当前线程进入阻塞状态,并且释放锁对象,sleep()方法并不会释放当前锁,若是不存在互斥的方法,则sleep的时候执行其他方法
ReadWriteLock 读写锁
原则:
写写/读写 需要”互斥“ 写数据的同时再写,可能造成数据错误,写数据的时候同时读,可能读到不完整的数据,所以都需要互斥
读读 不需要”互斥“ 并发的读取数据,并不需要互斥,不会造成差错
所以:读取数据的时候,可以允许有多个读锁,但是写数据的时候,只能有一个写锁,这种方式的效率,相对于独占锁来讲,至少并发读取数据方面,是有较大提升的
线程池:提供了一个线程队列,队列种保存着所有等待状态的线程。避免了创建与销毁的额外开销,提升响应速度。
线程池的体系结构:
java.util.concurrent.Executor:负责线程的使用与调度的根接口
|--ExecutorService:子接口,线程池的主要接口
|--ThreadPoolExecutor:实现类
|--ScheduledExecutorService:子接口,负责线程的调度
|--ScheduledThreadPoolExecutor:继承ThreadPoolExecutor和实现ScheduledExecutorService
工具类:Executors
ExecutorService: newFixedThreadPool():创建固定大小的线程池
ExecutorService:newCachedThreadPool():缓存线程池,线程池中的线程数量不固定,可以根据需求自动更改数量
ExecutorService:newSingledThreadPool():创建一个只有一个线程的线程池
ScheduledExecutorService:newScheduledThreadPool():创建固定大小的线程池,还可以定时或延时执行任务
Java 线程高级的更多相关文章
- Java线程的概念
1. 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...
- 细说进程五种状态的生老病死——双胞胎兄弟Java线程
java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...
- Java线程的5个使用技巧
萝卜白菜各有所爱.像小编我就喜欢Java.学无止境,这也是我喜欢它的一个原因.日常工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法.比如说线程.没错,就是线程 ...
- java线程的理解
java thread类都是native方法实现的,所以没有用平台无关的方法实现,怎么实现的呢? 线程的实现: 第一种:使用内核线程实现. 内核线程就是直接使用操作系统内核支持的线程,由内核完成切换. ...
- Java线程与Linux内核线程的映射关系[转]
Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程. Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是 ...
- Java线程池的原理及几类线程池的介绍
刚刚研究了一下线程池,如果有不足之处,请大家不吝赐教,大家共同学习.共同交流. 在什么情况下使用线程池? 单个任务处理的时间比较短 将需处理的任务的数量大 使用线程池的好处: 减少在创建和销毁线程上所 ...
- Java线程池与java.util.concurrent
Java(Android)线程池 介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行 ...
- Java线程(二):线程同步synchronized和volatile
上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程 ...
- 程序员的视角:java 线程(转)
在我们开始谈线程之前,不得不提下进程.无论进程还是线程都是很抽象的概念,有一个关于进程和线程很形象的比喻能帮我们更好的理解. 进程就像个房子,房子是一个包含了特定属性的容器,例如空间大小.卧室数量等. ...
随机推荐
- openresty入门文章(笔者自用)
推荐好的openresty入门介绍文章:https://www.cnblogs.com/digdeep/p/4859575.html
- [SHOI2016] 黑暗前的幻想乡 - 矩阵树定理,容斥
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 20; const in ...
- DTU DeepLearning: exercise 6
Does batch_size have any affects in results quality? how to set the optimal batch size and number ...
- HTML5使用JavaScript控制<audio>音频的播放
1.播放音乐最简单的样例 <audio controls> <source src="horse.mp3" type="audio/mpeg" ...
- spring boot使用freemarker模版整合spring Data JPA
目录结构 第一步:在pom.xml文件中添加依赖 <!--模板依赖--> <dependency> <groupId>org.springframework.boo ...
- IText异常 NoClassDefFoundError: org/bouncycastle/asn1/ASN1Encodable
根据Itext的版本,查看依赖库的版本 maven地址:https://mvnrepository.com/artifact/com.itextpdf/itextpdf <dependency& ...
- element 表格里的input点击回车聚焦下个input
<template> <card> <el-table ref="singleTable" :data="tableData" h ...
- ubuntu查看系统负载和程序运行状况
1,没有图形化界面 纯文字:top 美化的文字界面:htop 2,图形界面查看系统状态: gnome-system-monitor(或者在搜索界面中搜索system monitor) 3,jetson ...
- html+css 文本折叠
先看效果: 收缩状态 展开状态 源代码: <!doctype html> <html lang="zh"> <head> <meta ch ...
- 第五十三篇 Linux相关——Web服务器
No.1. Apache基本操作 安装:sudo yum -y install httpd 启动:service httpd start 停止:service httpd stop 查看服务运 ...