Java Thread概述

线程生命周期

Threadlife_20170208.jpg

线程状态:

  • 新建状态:使用new关键字和Thread类或其子类建立一个线程对象后
  • 就绪状态:当线程对象调用了start()方法之后,该线程进入就绪状态
  • 运行状态:如果就绪状态的线程获取CPU资源,就可以执行run()
  • 阻塞状态:
    • 等待阻塞:运行状态中的线程执行wait()方法
    • 同步阻塞:线程在获取 synchronized 同步锁失败
    • 其他阻塞:通过调用线程的sleep()或join()发出I/O请求时
  • 死亡状态:一个运行状态的线程完成人文或者其他终止条件发送

创建线程

1、继承Thread类

class ThreadDemo extends Thread

2、实现Runable接口

public class RunTest implements Runnable
   
Thread thread1 = new Thread(new RunTest());

3、通过Callable、Future、FutureTask创建线程

// 继承实现Callable接口,声明返回类型
class CallTest implements Callable<Long> 
    
FutureTask<Long> futureTask = new FutureTask<Long>(new CallTest(searchVo));

线程内置方法

1、sleep:使当前线程(即调用该方法的线程)暂停执行一段时间,让其它线程有机会继续执行,但它不会释放对象锁。
2、yield:暂停当前正在执行的线程对象,并执行其他线程。yield的目的是让相同优先级的线程之间能适当的轮转执行
3、join:把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如线程B中调用了线程A的JOIN()方法,直到线程A执行完毕后,才会继续执行线程B。

    //主线程等待子线程thread执行结束才会输出结果
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new JoinTest());
        thread.start();
        thread.join(); //加入join()
        System.out.println("主线程结束");
    }

4、setDaemon:
Java中线程分为两种类型:用户线程和守护线程。通过Thread.setDaemon(false)设置为用户线程;通过Thread.setDaemon(true)设置为守护线程。如果不设置次属性,默认为用户线程。

  public class DaemonTest extends Thread {
    public void run() {            //永真循环线程
        for (int i = 0; ; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
            }
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        Thread daemonTest = new DaemonTest();
        daemonTest.setDaemon(true);    //调试时可以设置为false,那么这个程序是个死循环,没有退出条件。设置为true,即可主线程结束,test线程也结束。
        daemonTest.start();
        System.out.println("isDaemon = " + daemonTest.isDaemon());
        try {
            System.in.read();   // 接受输入,使程序在此停顿,一旦接收到用户输入,main线程结束,守护线程自动结束
        } catch (IOException ex) {
        }
    }
}

如果线程设置为Thread.setDaemon(true),则主线程结束该程序不会结束,必须等待子线程执行结束整个程序才能结束;如果线程设置为Thread.setDaemon(false),则主线程结束整个程序就结束。

5、wait、notify、notifyAll
当一个线程进入wait之后,就必须等待其他线程notify/notifyAll,使用notifyAll可以唤醒所有处于wait状态的线程,使其重新进入锁的争夺队列中,而notify只能唤醒一个。
notify被唤醒的线程是随机的,所以通常是没办法指定是谁被唤醒。

线程关键字

  • volatile
    可见性:对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入
    原子性:对任意单个volatile变量的读/写具有原子性,但是类似于volatile++这种复合操作不具有原子性
  • synchronized
    当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
    synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
    synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法
public synchronized void accessVal(int newVal);  

synchronized 块:通过 synchronized关键字来声明synchronized 块

synchronized(syncObject) {  
//允许访问控制的代码  
}  

ThreadLocal

ThreadLocal是一个关于创建线程局部变量的类。通常情况下,我们创建的变量是可以被任何一个线程访问修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程无法访问和修改。

在Java中,栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。

ThreadLocal并不是存放在栈上。ThreadLocal实例实际上也是被其创建的类持有(更顶端应该是被线程持有)。而ThreadLocal的值其实也是被线程实例持有。它们都是位于堆上,只是通过一些技巧将可见性修改成线程可见。

//使用ThreadLocal保存Connection变量 
ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>(); 
//保存到线程本地变量中
connThreadLocal.set(conn);  
// 直接返回线程本地变量  
connThreadLocal.get();

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

推荐阅读更多精彩内容