2018/1/15 JAVA多线程相关
本文不说synchronized相关,它就是JAVA的一个保留关键字,jdk自己实现了它,但说真的,可应用场景真的少,相比lock接口,它还是被淘汰好吧;
首先,说说lock接口,lock接口是一个工具类,我们可以自己实现它,但是太麻烦,所以可以直接使用它的实现类,ReentrantLock();
它的方法有:lock() 这个方法可指定在那里上锁,但要记住,lock()方法在jvm抛出异常后不会自动解锁,所以需要我们使用try{}catch(){}块
来捕捉异常,之后在finally里将锁解开;
trylock() 此方法和lock方法相同,只是它会有一个返回值,如果当前线程获取到锁则为true,否则为false;我们可以利用此来做一些事情;例:
if(lock.trylock()){
syso("获得锁")
}else{
syso("没获取到锁")
}
trylock(long time,TimeUnit unit),和上面一个方法一样,只是有一个等待时间,并且可指定时间单元(时,分,秒)
lockInterruptibly()方法和之前几个不太一样,它更像是一个打断方法(是打断获取不到锁处于等待时期的线程,而并非已经获取到锁的线程),如果
一个线程获取不到锁而进入等待,之后又有另一个线程(一般为主线程)调用了它的lockInterruptibly()方法,它会立马中断并抛出异常;
ReentrantReadWriteLock()方法可以获得写锁和读锁,读锁可以多个线程获取到,而写锁则只有一个线程可以获取到,如果写锁被获取到,则读锁也无法被线程获取;
同理,如果读锁被获取到,则写锁会一直等待占用读锁的线程释放读锁;
公平锁:每个线程获取锁的顺序根据调用lock()方法的顺序;
非公平锁:每个线程获锁的顺序是随机的;
在ReentranReadAndWriteLock(Boolean bool);true为公平锁,false或不填则为非公平锁;
线程池:
SingleThreadExcutor; 只有一个线程的线程池,如果线程池中的线程正在工作,而有新任务来了,那么必须等当前线程工作完进入闲置状态才能开始新的任务
也正因此,此线程池可用于需要顺序提交任务的(说实话,很鸡肋,就算是多线程,我使用队列就能解决提交任务的顺序问题了);
CachedThreadPool;个人任务最好用的线程池,可以无限扩容(在性能允许的情况下),并且空置线程有个生命周期,默认为60秒,一旦60秒不被调用,即被销毁掉;
FixedThreadPool;见其名知其义,可以在创建的时候就定义好线程数量,并立即创建,如果没有任务,就一直处于等待状态,适合清楚知道并发量的场景下使用;
ScheduledThreadPool;这个没什么好说的,需要在创建的时候就定义线程数量,可以定时的处理一些任务,创建线程后,线程一直处于等待,直到指定时间才开始任务;
SingleScheduledThreadPool;上面的单例版.....(受不了这些单例版的线程池,既然都单例了,我还要你何用...)
Callable接口,和Runable接口不同的是,它是有返回值的(没错,异步执行,但却可以得到返回值...),返回值是一个Future对象,在实现Callable的时候定义泛型,泛型要与返回值一致(当然,直接将泛型类型传递到返回值即可);
与实现Runable的线程类使用start方法执行线程任务不同的是,Callable接口的线程实现类是通过submit执行线程任务,Future对象有个isDone()方法,返回True和False,是用来判断方法是否完成,get()方法则可以获取到返回值,当然,如果线程任务没完成会一直堵塞.
可以用来进行一些数据计算量比较大的逻辑,在主线程运行此线程后,直接在需要的地方get()一下就行.大大提高运行效率;
BlockingQueue 一个接口
下面有四个实现类,常用的两种为:ArrayBlockingQueue(需要在创建的时候自定义长度的),LinkedBlockingQueue(链表模式自然不用定义长度,当然你也可以定义,默认长度为Integer.MAX_VALUE)
这个没什么好说的,用来实现中间件的,了解即可,其实就是几个方法,有的获取不到元素就一直堵塞直到有元素,有的元素满了就等待有空位置再去添加;
Volatile关键字
这个就得好好说说了,而且得从JVM运作原理说起,我们JVM执行任务的时候啊,不是在我们电脑里那些4G啊,8G啊内存中执行的,而是在CPU中的一小块内存区域执行的(为什么?因为快啊),
我们硬盘里的内存叫做主内存,而CPU的内存呢,则叫工作内存,在多线程情况下,因为现在都是多核了,自然有多个CPU,多个工作内存,而在不加Volatile关键字的情况下,我们多个工作内存
会将一个公共的成员数据的值复制一份放在它们各自的内存中,但如果加了Volatile关键字的话,它们拿的就只是个引用(也就是数据在内存中的地址),这样每次其它线程对数据做操作的时候,其它的
线程都知道,毕竟它们操作的是同一份数据,这样也就保证了并发情况下的可见性.但是!!!不要以为高并发情况下加了它就安全了,它数据操作非原子性的情况下也不是线程安全的(什么叫原子性?就是操作细粒度最小的级别,比如赋值啊,对一个数字+1(只是+1,但不赋值,要不然就是两步操作了)),
这样会导致一个情况,比如你一个线程对一个数据进行++的操作,例:X++;在我们看来是一步,但CPU要进行4步,先拿到值,再+1,再赋值,最后返回值.这样在中途的话可能会切换到其它线程.而此时数据并没有更新到主内存,其它线程拿到的依旧是没有更新前的数据.自然就产生了脏数据;
所以Volatile关键字的应用场景一般用来做原子性的操作就好~
2018/1/15 JAVA多线程相关的更多相关文章
- Java多线程相关的
很多小伙伴在学习Java的时候,总是感觉Java多线程在实际的业务中很少使用,以至于不会花太多的时间去学习,技术债不断累积!等到了一定程度的时候对于与Java多线程相关的东西就很难理解,今天需要探讨的 ...
- Java多线程相关面试题及答案-整理
1.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速.比如,如果一个线程完成 ...
- Java[3] Java多线程相关资料
Java多线程: http://www.uml.org.cn/j2ee/201509093.asp
- -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中
本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait( ...
- 2018.4.17 java多线程练习二模拟开场仪式进场
2.某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程, 并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码.线程 ...
- 2018.4.16 Java多线程实现龟兔赛跑
龟兔赛跑(通过多线程来实现 里面的具体方法) TT.java package com.lanqiao.demo3; /** * 乌龟 * @author Administrator * */ publ ...
- java多线程相关代码
1.创建线程的三种方式 使用Thread package com.wpbxx.test; //1.自定义一个类,继承java.lang包下的Thread类 class MyThread extends ...
- 2018.6.15 Java对象序列化详解
一.定义 Serializable 序列化:把Java对象转换为字节序列的过程. 反序列化:把字节序列恢复为Java对象的过程. ObjectOutputStream对象输出流 可以将实现了Seria ...
- Java多线程相关的常用接口
Runnable 是一个接口,里面只声明了一个方法run();返回值为void所以无法拿到执行完的结果.只能通过共享变量或者线程通信来搞定.Future就是对具体的Runable或者Callable任 ...
随机推荐
- nxlog4go 简介 - 基于log4go的下一代go语言日志系统
nxlog4go的项目网址: https://github.com/ccpaging/nxlog4go 项目历史 ccpaging's log4go forked from https://githu ...
- Python 爬取美女图片,分目录多级存储
最近有个需求:下载https://mm.meiji2.com/网站的图片. 所以简单研究了一下爬虫. 在此整理一下结果,一为自己记录,二给后人一些方向. 爬取结果如图: 整体研究周期 2-3 天, ...
- Powerdesigner+Execel
1.将Powerdesigner中的表(PDM)导入到execel中 Ctrl+Shift+X/tool->Execute commands ->Edit/Run script 粘贴如下v ...
- 互联网公司为啥不使用mysql分区表?
转:http://www.cnblogs.com/zhulin516114/p/7306708.html 缘起:有个朋友问我分区表在58的应用,我回答不出来,在我印象中,百度.58都没有听说有分区表相 ...
- scrapy_cookie禁用_延迟下载_自定义爬虫setting
如何设置禁止cookie? 在setting中 添加字段: COOKIE_ENABLED = False # False关闭cookie,True ...
- python_如何对迭代器进行切片操作
案例: 对于某个文件,我只想读取到其中100~200行之间的内容,是否可以通过切片的方式进行读取? 我想: f = open() f[100:200] 可行? 如何解决这个问题? 方法1: 全部读取到 ...
- python_如何实现可迭代对象和迭代器对象?
什么是可迭代对象? 列表.字符串 for循环的本质? for循环要确保in后面的对象为可迭代对象,如何确保? iter() 方法得到一个迭代器对象 不停.__next__() 方法对迭代器对象进行迭代 ...
- Windows核心编程&内存管理
1. 每个进程都有自己的虚拟地址空间,对于32位机器而言,这个地址空间的大小为4GB(2^32 / 1024^3),这个虚拟地址空间只不过是一个内存地址空间, 为了能够正常读/写数据,我们还需要把物理 ...
- Log4j源码解析--核心类解析
原文出处:http://www.blogjava.net/DLevin/archive/2012/06/28/381667.html.感谢上善若水的无私分享. 在简单的介绍了Log4J各个模块类的作用 ...
- Linux指令--chmod
chmod命令用于改变linux系统文件或目录的访问权限.用它控制文件或目录的访问权限.该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. Linux系统中的每 ...