JAVA从入门到精通之多线程详情
小标 2018-06-05 来源 : 阅读 644 评论 0

摘要:在JAVA从入门到精通中,首先了解线程的五大状态:新建,就绪,运行,阻塞,终结。希望看完本文对大家学习JAVA从入门到精通有所帮助。

    在JAVA从入门到精通中,首先了解线程的五大状态:新建,就绪,运行,阻塞,终结。希望看完本文对大家学习JAVA从入门到精通有所帮助。

1、新建状态(New):新创建了一个线程对象。

2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权。即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

阻塞的情况分三种:

(1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

线程变化的状态转换图如下:

线程的实现方法

实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样, 当我们new了这个对象后,线程就进入了初始状态; 当该对象调用了start()方法,就进入就绪状态!

在工作中,因为需要获取返回值的线程,接触到了callable接口

Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定, Callable只能由ExecutorService.submit() 执行,正常结束后将返回一个future对象,实例如下:

ExecutorService pool = Executors.newFixedThreadPool(10);

Callable c1 = new YkuploadRunable(");

Future f1 = pool.submit(c1);

System.out.println(f1.get());

pool.shutdown();

线程的经典问题:生产者和消费者问题

生产者可以将产品放入仓库,消费者则可以从仓库中取走产品,要有保护仓库为空或溢出

解决生产者/消费者问题的方法可分为两类:

1.采用某种机制保护生产者和消费者之间的同步;

2.在生产者和消费者之间建立一个管道。

实现方法有

1.object.wait(),object.notify();

2.condition.await(),condition.signal();

3.LinkedBlockingQueue list; put(),take()会自动阻塞

方法一的具体代码

仓库.java

+ View Code

生产者.java

+ View Code

消费者.java

+ View Code

方法二的实现如下:注意lock的lock(),unlock()

+ View Code

方法三的实现如下:

+ View Code

线程同步

同步锁synchronized

上面的wait(),await()

还有一种join方法,使线程顺序进行。

线程实战

因为需要在controller中同时上传多个视频并保存返回的视频id进数据库,所以在controller中写了一个内部类,具体代码如下:

+ View Code

后记:貌似不能同时上传同一个文件,多个视频上传速度还是取决于你的带宽!.

线程池

线程池,顾名思义存放线程的池子,可以类比数据库的连接池。因为频繁地创建和销毁线程会给服务器带来很大的压力。若能将创建的线程不再销毁而是存放在池中等待下一个任务使用,可以不仅减少了创建和销毁线程所用的时间,提高了性能,同时还减轻了服务器的压力。

初始化线程池有五个核心参数,分别是 corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue。还有两个默认参数 threadFactory, handler

corePoolSize:线程池初始核心线程数。初始化线程池的时候,池内是没有线程,只有在执行任务的时会创建线程。

maximumPoolSize:线程池允许存在的最大线程数。若超过该数字,默认提示RejectedExecutionException异常

keepAliveTime:当前线程数大于核心线程时,该参数生效,其目的是终止多余的空闲线程等待新任务的最长时间。即指定时间内将还未接收任务的线程销毁。

unit:keepAliveTime 的时间单位

workQueue:缓存任务的的队列,一般采用LinkedBlockingQueue。

threadFactory:执行程序创建新线程时使用的工厂,一般采用默认值。

handler:超出线程范围和队列容量而使执行被阻塞时所使用的处理程序,一般采用默认值。

在接收任务前,线程池内是没有线程。只有当任务来了才开始新建线程。当任务数大于核心线程数时,任务进入队列中等待。若队列满了,则线程池新增线程直到最大线程数。再超过则会执行拒绝策略。

举个栗子:

+ View Code

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程