Java创建多线程的三种方式

前言

这篇文章主要讲述线程的概念、组成、Java创建多线程的三种方式以及线程的类型。

线程概念

线程和进程的区别

进程:正在运行的程序,例如:你打开 的qq音乐.exe程序,其由PCB(进程控制块)、栈、程序、数据组成。

线程:是一个进程中的程序代码的一个执行序列,被认为是带有自己的程序代码和数据的虚拟处理机的封装,其由处理机、代码、数据三部分组成,你可以这样理解线程是在进程内部同时做的事情,比如你在qq音乐应用里可以一边听音乐、同时下载音乐。这就是由多线程来实现的。(一个进程至少包含一个或者多个线程)

注意:

  1. 每个Java程序都有一个隐含的主线程,即main()方法,要实现多线程必须在主线程中创建新的线程,Java语言使用Thread类及其子类的对象来表示线程;

  2. 一个虚拟处理机封装在java.lang.Thread类中,它控制着整个线程的运行;CPU执行的代码传递给Thread类,由Thread类控制顺序执行;处理的数据传递给Thread类,是在代码执行的过程中所要处理的数据。代码和数据可以由多个线程共享,也可以不被共享,代码和数据是相互独立的,当两个线程共享同一个类的实例时,他们就共享相同的代码;当两个线程共享一个公共对象的存取时,他们就共享相同的数据。

线程的生命周期

一个线程从它被创建到停止执行要经历一个完整的生命周期,在这个生命周期中有4种不同的状态。

①New(新) ②Runnable(可运行) ③Blocked(被阻塞) ④Dead(死亡)

创建线程的三种方式

通过继承Thread类

package thread;

public class ThreadTest extends Thread{
    
    String threadName;
    
    public ThreadTest1(String s){
        System.out.println("Making thread:"+s);
        threadName = s;
    }
    
    public void run(){
        for( int i = 0; i < 3; i++ ){
            System.out.println("Running thread number =" + threadName);
            try {
                Thread.sleep(1000); //线程睡眠1秒
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    //主线程,操作系统调度每个线程执行
    public static void main(String[] args){
        
        ThreadTest1 thread1 = new ThreadTest1("Tom"); //线程1Tom
        ThreadTest1 thread2 = new ThreadTest1("Jack"); //线程2Jack
        
        /**线程启动,不是直接调用 run() 方法,而是调运线程类 Thread 的 start() 方法,
        *在 Thread 方法内部会调用本地系统方法,最终会自动调用自己线程类的 run()方法。
        **/
        thread1.start(); 
        thread2.start();
        System.out.println("End of main");
    }
}

运行截图

image

通过实现Runnable接口

package thread;

public class ThreadTest implements Runnable{
    
    String threadName;
    
    public ThreadTest(String s){
        System.out.println("Making thread:"+s);
        threadName = s;
    }
    
    public void run(){
        for( int i = 0; i < 3; i++ ){
            System.out.println("Running thread number =" + threadName);
            try {
                Thread.sleep(1000); //让线程睡眠1秒
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    //主线程,操作系统调度每个线程执行
    public static void main(String[] args){
        
        //创建线程Tom和线程Jack
        Thread thread1 = new Thread(new ThreadTest("Tom")); 
        Thread thread2 = new Thread(new ThreadTest("Jack")); 
        
        /**线程启动,不是直接调用 run() 方法,而是调运线程类 Thread 的 start() 方法,
        *在 Thread 方法内部会调用本地系统方法,最终会自动调用自己线程类的 run()方法。
        **/
        thread1.start(); 
        thread2.start();
        System.out.println("End of main");
    }

}

运行截图

image

通过实现Callable接口

package thread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class ThreadTest implements Callable<Integer>{
    
    String threadName;
    
    public ThreadTest(String s) {
        System.out.println("Making thread:"+s);
        threadName = s;
    }

    @Override
    public Integer call() throws Exception {
        int sum = 0;
        // TODO Auto-generated method stub
        for( int i = 0; i < 5; i++ ){
            System.out.println(threadName+i);
            sum += i;   
        }
        return sum;
    }
    
    public static void main(String args[]){
        
        //创建两个线程,并且启动
        ThreadTest threadTest1 = new ThreadTest("Tom");
        ThreadTest threadTest2 = new ThreadTest("Jack");
        
        FutureTask<Integer> result1 = new FutureTask<>(threadTest1);
        new Thread(result1).start();
        
        
        FutureTask<Integer> result2 = new FutureTask<>(threadTest2);
        new Thread(result2).start();
    }

}

运行截图

image

线程类型分类

java中线程一共有两种类型,守护线程和用户线程,用户线程又叫非守护线程。

  • 守护线程

可以通过thread.setDaemon(true)方法设置线程是否为守护线程,thread.setDaemon(true)必须在thread.start()之前设置,否则会抛出IllegalThreadStateException异常。在守护线程中开启的新线程也是守护线程。守护线程顾名思义是用来守护的,是给所有的非守护线程提供服务的,所以在JVM执行完所有的非守护线程后,JVM就会停止,守护线程也不在运行,最典型的守护线程就是java的垃圾回收机制(GC)。

  • 非守护线程

java线程默认设置为非守护线程thread.setDaemon(false)。当主线程运行完之后,只要主线程里有非守护线程JVM就互惠退出,直到所有的非守护线程执行完之后JVM才会退出。、

总结:如果把一个线程设置成守护线程,则JVM的退出就不会关心当前线程的执行状态。

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

推荐阅读更多精彩内容

  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,949评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,438评论 1 15
  • 林炳文Evankaka原创作品。转载自http://blog.csdn.net/evankaka 本文主要讲了ja...
    ccq_inori阅读 645评论 0 4
  • 一、认识多任务、多进程、单线程、多线程 要认识多线程就要从操作系统的原理说起。 以前古老的DOS操作系统(V 6....
    GT921阅读 1,009评论 0 3
  • 【JAVA 线程】 线程 进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者...
    Rtia阅读 2,758评论 2 20