(二)线程生命周期与Java关键字

进程与线程

进程是并发执行的程序在执行过程中分配和管理资源的基本单位。而进程是线程的容器,一个进程下可以有多个线程。

线程的生命周期

Thread的生命周期记录在内部的State中:

public enum State {
        NEW,
        RUNNABLE,
        BLOCKED,
        WAITING,
        TIMED_WAITING,
        TERMINATED;
    }

1.新建线程与启动线程

Thread t = new Thread();
t.start();

2.终止线程

  • Thread.stop()方法可以终止线程,但是已经被标注为废弃方法,因为该方法会直接释放线程持有的锁,可能会造成锁维护的对象的不一致状态。
  • 安全的退出方法:可以在线程中监听一个状态值,需要退出时由线程自己按既定步骤退出。

3.线程中断

public void Thread.interrupted();  // 中断线程
public boolean Thread.isInterrupted();  // 判断线程是否被中断
public static boolean Thread.interrupted();  // 判断线程是否被中断,并清除当前中断状态

线程中断可以用来代替Thread.stop()方法实现主动停止线程。线程中断并不会使线程立刻退出,而是向线程发送一个中断通知,目标线程接到通知之后如何处理,完全由目标线程自己决定。

Thread t1 = new Thread() {
    @Override
    public void run() {
        while (true) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("quit");
                break;
            }
        }
        Thread.yield();  // 让出自己的时间片给其他线程
    }
};

相对于之前的监听普通标记物的方法,中断命令由JDK提供支持,可以使Thread.sleep()Object.wait()等方法执行时抛出InterruptedException异常。因此更为泛用。(Thread.sleep()在抛出异常之后会清除中断状态,如果需要在捕捉到中断异常之后检测中断状态,还需要重新手动设置中断状态)

public static native void sleep(long millis) throws InterruptedException;
public final void wait() throws InterruptedException

4.等待(wait)和通知(notify)

public final void wait() throws InterruptedException
public final native void notify();
public final native void notifyAll();

wait()方法和notify()方法属于java.lang.Object对象。当在一个对象实例上调用wait()方法之后,当前线程就会在这个对象上等待。
如果在线程A中调用了obj.wait()方法,那么线程A就会停止继续执行,转为等待状态,直到其他线程调用了obj.notify()方法为止。相当于obj对象成为了线程间通信的媒介。
当一个线程调用了obj.wait()方法,那它就会进入obj对象的等待队列中,当obj.notify()方法被其他线程调用时,会唤醒等待队列中的一个线程,这个唤醒是不公平、完全随机的。如果调用的是obj.notifyAll()方法,则会唤醒等待队列中的所有线程。
想要使用obj.wait()obj.notify()方法,必须先使用synchronized获取obj对象,因为wait()notify()方法执行前需要先获得obj对象的一个监视器,执行之后再释放obj的监视器给其他等待中的线程。
Thread.sleep()Object.wait()方法都可以使线程等待若干时间,除了Object.wait()方法可以被唤醒外,Object.wait()方法还会释放obj的锁,而Thread.sleep()不会释放任何资源。

5.挂起(suspend)和继续执行(resume)

Thread.suspend()同样可以暂停线程,但是不会释放线程持有的资源,容易导致系统工作不正常,因此已被标为废弃。

6.等待线程结束(join)和谦让(yeild)

public final void join() throws InterruptedException  // 无限制等待
public final synchronized void join(long millis) throws InterruptedException  // 等待一段时间

当一个线程的执行依赖其他线程的执行结果时,就需要该线程等待目标线程执行结束后再继续执行。要做到这一点,可以使用wait()方法,而Java提供的join()方法同意可以做到。

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread();
        t.start();
        t.join();
        System.out.println("Hello World");
    }
}

主线程调用t.join()方法,等t线程结束执行之后再继续执行。join()方法本质是让调用线程wait()方法在当前对象实例上。JDK中join()方法的实现核心片段如下:

while(isAlive()) {
    wait(0);
}

Thread.yield()方法可以使当前线程让出CPU资源,在这之后,该线程会立即加入之后的CPU资源争夺中,因此仍有可能继续执行。

public static native void yield();

Java关键字

1.volatile

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
  • 禁止进行指令重排序。

因此,volatile关键字可以保证一个变量的可见性与一定程度上的有序性:

  • 当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
  • volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作

volatile关键字并不能保证操作的原子性,如果一个变量进行的操作是非原子性的,如自增(++),那么即使它是volatile变量,这个操作也是非原子性的。

2.synchronized关键字

关键字synchronized的作用是实现线程之间的同步。它的工作是对同步的代码加锁,使得每一次,只能有一个线程进入同步块,从而保证线程的安全性。

  • 指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。
  • 直接作用于实例方法:相当于对当前实例对象加锁,进入同步代码前要获得当前实例对象的锁。
  • 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。

除了用于线程同步,确保线程安全外,关键字synchronized还可以保证线程之间的可见性和有序性。

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

推荐阅读更多精彩内容

  • 本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...
    eddy_wiki阅读 2,130评论 0 14
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,110评论 0 8
  • 相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对...
    东经315度阅读 1,943评论 0 8
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,959评论 1 18
  • 生活在当今这个快节奏的社会中,我们每一个人就像是一个战士,每天早上从起床开始,就打算着如何为了自己理想去战斗、去拼...
    高桥美莎阅读 363评论 4 26