Java线程学习

Java创建一个线程,最简单的方法就是从Thread类继承。这个类包含了创建和运行线程所需的一切东西。Tread最重要的方法是run()。但为了使用run(),必须对其进行重载或者覆盖,使其能充分按自己的吩咐形式。因此,run()属于那些会与程序中的其他线程“并发”或“同时”执行代码。

//simpleThread.java
public class SimpleThread extends Thread {
    ......
    public void run(){
        // do something ......
    }
}

Thread包含一个特殊的方法 start(),它的作用是对线程进行特殊的初始化,然后调用 run() 。所以整个步骤包括:调用构建器来构建对象,然后用 start() 配置线程,再调用 run() 。如果不调用 start(),线程便永远不会启动。

Java操作共享资源时,为了保证共享资源信息数据一致性,在调用共享资源的方法使用,需要采用“同步”方式操作,即调用"synchronized"方法。调用任何synchronized方法时,对象就会被锁定,不可再调用那个对象的其它任何synchronized方法,除非第一个方法完成了自己的工作,并解除锁定。下面列出简单的synchronized的方法:

    synchronized void f(){
        // do something ......
     }

     synchronized void g(){
        // do something ......
     }

重要规则:对于访问某个关键共享资源的所有方法,都必须把它们设为synchronized,否则就不能正常地工作。

一个线程的四个状态:

  • 新(New):线程对象已经创建,但尚未启动,所以不可运行。
  • 可运行(Runnable):意味着一旦时机分片机制有空闲的CPU周期提供给一个线程,那个线程便立即开始运行。因此,线程可能在、也可能不在运行当中,但一旦条件许可,没有什么能阻止他的运行——它既没有“死”掉,也未被“堵塞”。
  • 死(Dead):从自己的run()方法中返回后,一个线程便已“死”掉。亦可调用stop()令其死掉,但会产生一个违例——属于Error的一个子类(也就是说,我们通常不捕获它)。记住一个违例的“掷”出应当是一个特殊事件,而不是正常程序运行的一部分。所以不建议你使用stop()(在Java 1.2 则是坚决反对)。另外还有一个destroy()方法(它永远不会实现),应该尽可能地避免调用它,因为它非常武断,根本不会解除对象的锁定。
  • 堵塞(Blocked):线程可以运行,但有某种东西阻碍了它。若线程处于堵塞状态,调度机制可以简单地跳过它,不给它分配任何CPU 时间。除非线程再次进入“可运行”状态,否则不会采取任何操作。

线程为何会堵塞?
堵塞状态是前述四种状态中最有趣的,值得我们作进一步的探讨。线程被堵塞可能是由下述五方面的原因造成的:
1.调用sleep(毫秒数),使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的。
2.用suspend()暂停了线程的执行。除非线程收到resume()消息,否则不会返回“可运行”状态。
3.用wait()暂停了线程的执行。除非线程收到nofify()或者notifyAll()消息,否则不会变成“可运行”(是的,这看起来同原因2 非常相象,但有一个明显的区别是我们马上要揭示的)。
4.线程正在等候一些IO(输入输出)操作完成。
5.线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。

亦可调用yield()(Thread 类的一个方法)自动放弃CPU,以便其他线程能够运行。

死锁
由于线程可能进入堵塞状态,而且由于对象可能拥有“同步”方法——除非同步锁定被解除,否则线程不能访问那个对象——所以一个线程完全可能等候另一个对象,而另一个对象又在等候下一个对象,以此类推。这个“等候”链最可怕的情形就是进入封闭状态——最后那个对象等候的是第一个对象!此时,所有线程都会陷入无休止的相互等待状态,大家都动弹不得。我们将这种情况称为“死锁”。

为减少出现死锁的可能,Java 1.2 作出的一项贡献是“反对”使用Thread 的stop(),suspend(),resume() 以及destroy()方法。
suspend()和resume() 方法天生容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被“挂起”的线程恢复运行。

推荐:使用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个
notify()重新启动线程。

线程安全性:当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的对于线程安全类的实例进行顺序或并发的一系列操作,都不会导致实例处于无效状态。

无状态对象永远是现场安全的。

原子变量
线程安全性定义要求无论是多线程中的时序或交替操作,都要保证不破坏那些不变约束。当一个不变约束涉及多个变量时,变量间不是彼此独立的:某个变量的值会制约其他几个变量的值。因此,更新一个变量的时候,要在同一原子操作中更新其他几个。

为了保护状态的一致性,要在单一的原子操作中更新相互关联的状态变量。

加锁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,949评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,438评论 1 15
  • 一. 概述 使用的线程的目的有如下几点: 异步。所谓异步,字义上来讲就是同时做多个不同的事。例如,你正在和恋人聊Q...
    DCRain阅读 296评论 0 2
  • 林炳文Evankaka原创作品。转载自http://blog.csdn.net/evankaka 本文主要讲了ja...
    ccq_inori阅读 643评论 0 4
  • 文章来源:http://www.54tianzhisheng.cn/2017/06/04/Java-Thread/...
    beneke阅读 1,469评论 0 1