我们在网上可以看到所有有关于java的线程的基本概念的很多解释,不乏有很多详细经典的解释和代码解说。但是我们的很多初学者看完不能有一个直观的印象,特别是一些没有编程基础的学习者,很多时候要花很多时间去理解。我希望这篇文章能给初学者一个很直观,很容易理解的角度去学习。

一、java线程的生命周期

了解一个东西,要搞清楚它是怎么运作的。搞清楚内部的来龙去脉是一个学习极好的角度,而生命周期是一个很好的着手点。一个图来解释

我们只要了解上面图每一种状态的关系和相互转换就可以了,线程也就了解的一半了。

1.好,现在来看看线程开始,以new Thread()的方式诞生。

2.start()的方式进入线程的运行状态,当然线程没有直接进入运行状态,而是先进入了"可运行状态",即“就绪状态”,在调用了run()方法后才进入运行状态。好了,线程跑起来了。

(图中没有显示run()方法,当然你可以不用start(),直接使用run(),但是差别很大。Start方法让线程进入一个多线程的状态,特别是多个线程的时候,CPU会给每个线程标记,比如1号Thread、2号Thread. . . . . .如果你直接run()起来,CPU就不管你啦。不管你多少个有关于这个对象的线程,都是没有标记,就想一群脱缰的野马,控制不了。)

3.就像人一样,生命的开始和结束之间,我们除了在“奋斗”和“准备奋斗”的状态之外,另外一种状态是在休息。线程的“休息状态“就是“阻塞状态”,我们有很多种方法从“奋斗状态”转换到“休息状态”。而线程也一样,从“运行状态”到“阻塞状态”,即是wait()方法。那从“就绪状态”如何返回“运行状态”呢?对不起,不能直接到达“运行状态”,要先到“就绪状态”再到“运行状态”,而线程从“阻塞状态”到“就绪状态”使用notify()或者notifyAll()。

4.有时候我们不想去休息,只是想处于一种“暧昧”状态,可进可退。线程的“可运行状态”就是“暧昧状态”。线程如何从“运行状态”转换为“可运行状态”呢?方法很简单,sleep()和yield()。两者的区别是一个是可以定时,一个不可以。

5.然后线程进入了“可运行状态”后,如果有多个线程都想进入“运行状态”,CPU如何办?好办,java中可以给线程设置优先级,等级高就先执行罗。如果等级一样如何办?好办,公平竞争,谁厉害谁上罗(其实是随机吧,点到谁谁上)。

二、实现方式

我们了解了线程的生命历程,那我们如何创建他们呢?

  1. 实现Runnable接口
  2. 继承Thread父类

区别:这两个有什么区别

A:实现Runnable接口一个是可以摆脱java中单继承的困扰,继承Thread太单调。我们喜欢多多益善对嘛。

B:实现Runnable的优势,是多个线程共享这个对象的数据。如果是继承Thread,多个线程是各用各用的东西。

三、对象

Java中一切皆为对象。我们要线程干嘛?不就是为了来“搞对象”啦。于是我们在“搞对象”的过程中,就出现了一个问题。就一个对象,但是很多个线程都想搞它如何办?

为了协调这些线程的矛盾,java就又提出了一个关键字synchronized。这个synchronized很叼的,它就像一个裁判。有一个线程a想来用对象,如果里面有线程b。裁判就会对外面的线程a说:“对不起,里面有了线程b了。要等下,等线程b用完了对象才能让你进来”。所以很多代码要保证对象的唯一性,就要用到synchronized。

像“售票系统”,很多个客户端都来抢票,如何保证票不被多抢,导致票没了还有客户端再抢。

四、总结

本文没有代码介绍,网上已经有很多对于线程的介绍。希望读者在看完这篇文章后有一个对线程具体化的概念,在结合一个个知识点看看大神们的代码介绍就更为深刻。当然有错误的地方希望大家多多提醒。

最新文章

  1. js框架模版
  2. PHP测试用例文档
  3. ATT 解锁手机
  4. 如何选择Html.RenderPartial和Html.RenderAction
  5. 论文笔记之:Asynchronous Methods for Deep Reinforcement Learning
  6. pku ppt some problem
  7. oracle时间模型
  8. [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
  9. Jmeter使用代理服务器录制脚本
  10. Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集
  11. IOS开发之XCode学习012:Slider和ProgressView
  12. obj-c编程11:内存管理和ARC(自动引用计数)
  13. localStorage sessionStorage 用法
  14. Java学习笔记四:三目运算符与字符串连接符等
  15. 使用CSS兄弟选择器完成复杂垂直边距(vertical margins)的设计
  16. Ubuntu下配置使用mysql
  17. gitlab无法push或clone的错误:JWT::DecodeError (Nil JSON web token): lib/gitlab/workhorse.rb:120:in `verify_api_request!'
  18. 唯品会osp简介(转)
  19. myeclipse越来越卡了怎么回事啊?
  20. mvc bundle的介绍及使用 转载自 http://www.ityouzi.com/archives/mvc-bundleconfig.html

热门文章

  1. 给指定的div增加滚动条
  2. 启动mysql遇到问题Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
  3. IDEA控制台输出中文乱码日志文件正常
  4. part8 详情页面动态路由以及banner布局
  5. 使用svn时出现Can't switch /XXX/XXX because it is not the repository yet
  6. 9 react 基础 - 虚拟DOM
  7. 吴裕雄--天生自然 JAVASCRIPT开发学习:prototype(原型对象)
  8. linux下ffmpeg环境搭建记录
  9. 洛谷 P1060开心的金明
  10. MySql、Mongodb和Redis的区别