欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程

程序员文章站 2022-05-02 10:02:07
...

线程相关概念

程序:progarm 静态的概念,是计算机指令有序的集合
进程:process 动态的概念,代表程序的依次执行
线程:thread 进程中的一条执行任务的最小单位

进程特点
1.进程可以并发执行
2.进程是系统进行资源分配的最小单位
3.多个进程间不共享相互的资源,每个进程独享系统分配的资源
4.系统中创建和销毁进程,消耗的资源是比较大的
5.一个进程包含多个线程,至少包含一个线程。

线程特点:
1.线程可以并发执行
2.线程是系统进行运算调度的最小单位
3.对个线程共享一个进程的系统资源,但每个线程又有各自的调用栈、寄存器环境、线程本地存储
4.系统中创建和销毁线程,消耗的资源很小;线程是轻量级进程
5.线程不能独立存在,必须存在于某个进程中
6.进程中的任务都是要靠线程来完成,进程对应的程序中的每一行代码都是要靠某一个线程来执行
7.当一个程序启动的时候,系统为为其创建一个线程。JAVA程序中成为main线程-主线程。(主线程只是因为main的英文意思是才称其为“主线程”的)。主线程执行的路径就是main方法的主体部分

多线程

多线程的优点
单线程程序问题:一旦线程被阻塞,那么整个进程就被阻塞了,只有解除阻塞,程序才会继续运行。
多线程程序优点:多线程的程序可以被CPU执行的概率更大。若其中一个线程被阻塞,不会影响其他的线程。
线程相关小知识点
java程序的第一个线程,是main线程–“主线程”,是由JVM创建的。
java.lang.Thread:来描述线程对象的

java创建线程的三种方式

第一种方法:继承Thread类

package com.lyx.io;
/**
 * 创建自定义线程的三种方式
 * 第一种:继承线程类
 * 实现方式:在线程的子类中,重写run方法,run方法的主体就是线程子类对象的任务
 */
public class TestThread {
    public static void main(String[] args) {
        //创建线程对象
        MyThread myThread = new MyThread();
        //启动线程
        myThread.start();
        //main线程也同时打印1-10000
        for (int i = 0; i < 10000; i++) {
            System.out.println(Thread.currentThread().getName()+"--->"+i);
        }
    }
}
//线程类
class MyThread extends Thread{
    //子线程任务打印1-10000
    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            //得到当前线程的名字
            System.out.println(this.getName()+"--->"+i);
        }
    }
}

第二种方法:实现Runnable接口

package com.lyx.io;
/**
 * 创建自定义线程的三种方式
 * 第二种:实现Runnable接口
 * 实现方式:定义任务类,在任务类重写run方法,然后把任务交给Thread类的对象去执行
 */
public class TestRunnable {
    public static void main(String[] args) {
        //创建线程任务类对象
        MyRunnable myRunnable = new MyRunnable();
        //创建Thread类对象
        Thread thread = new Thread(myRunnable);
        //启动线程
        thread.start();

        //main方法线程的for循环,打印1-10000
        for (int i = 0; i < 10000; i++) {
            System.out.println(Thread.currentThread().getName()+"--->"+i);
        }
    }
}
//线程类  需要实现java.lang.Runnable
class MyRunnable implements Runnable{
    //重写run方法
    @Override
    public void run() {
        //子线程任务打印1-10000
        for (int i = 0; i < 10000; i++) {
            System.out.println(Thread.currentThread().getName()+"--->"+i);
        }
    }
}

总结两种方式的优缺点

l 继承线程类:优点:比较容易理解,代码实现简单。缺点:多个线程对象共享同一个数据的实现相对复杂。

l 实现Runnable接口:优点:多个线程执行同一个任务,实现比较简单。也就是多个线程共享同一个数据。缺点:相对理解复杂,代码实现相对复杂。

第三种方法:实现Callable接口

package com.lyx.io;

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

/**
 * 创建自定义线程的三种方式
 * 第三种:实现Callable接口
 * 实现方式:在线程的子类中,重写call方法,call方法的主体就是线程子类对象的任务
 */
public class TestCallable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //线程类实例化
        MyCallable myCallable = new MyCallable();
        //创建FutureTask对象,它实现了Runnable接口,用来调度管理线程任务类
        FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
        //创建Thread对象
        Thread thread = new Thread(futureTask);
        thread.start();

        //输出结果
        System.out.println("线程获得结果:"+futureTask.get());//此处throws抛出异常
    }
}
//线程类 需要实现java.util.concurrent.Callable
class MyCallable implements Callable<Integer>{
    //泛型规定了方法的返回类型
    //call方法就是线程任务主体
    @Override
    public Integer call() throws Exception {
        Thread.sleep(500);//休眠500毫秒
        //返回0-99随机数
        return (int)(Math.random()*100);
    }
}

第三种方式和其他的两种方式的区别:

l Call 方法有返回类型,可以根据泛型指定,其他的两种方式,run方法返回类型为void。第三种方式可以任务执行完毕之后,得到一个你想得到的值。通过get去获得该结果。

l run方法的实现中,如果存在有异常产生的内容,那么只能使用try-catch 来处理,不能通过throws 来处理。call 方法定义的时候就抛出了Exception。所以多了一种选择,如果call 方法中存在异常代码,可以不做任何的处理,也就是可以不使用try-catch 来捕获。

线程的生命周期

线程

程的常用方法

未完待续

相关标签: 线程