Java多线程的创建

进程是操作系统资源分配的基本单位,每个进程拥有独⽴的虚拟内存空间(代码、数据、系统资源),相互隔离,通信成本⾼(如管道、消息)。
线程是CPU调度的基本单位,属于同⼀进程的多个线程共享进程的内存和资源,通信⾼效(直接读写共享变量),但⼀个线程崩溃可能导致整个进程终⽌

并发(concurrent):是指如何正确、⾼效地控制共享资源。
并⾏(parallel):是指如何利⽤更多的资源来产⽣更快速的响应。

并发通常是指多个任务在进⾏,⽽并⾏则更多是指多个任务在同时执⾏。

并发:同时处理多个任务,即不必等待⼀个任务完成就能开始处理其它任务。并发解决的是阻塞问题,即⼀个
任务必须要等待⾮其可控的外部条件满⾜后才能继续执⾏,最常⻛的例⼦是I/O,⼀个任务必须要等待输⼊才能执⾏(即被阻塞),类似的场景称为I/O密集型问题。
并⾏:同时在多处执⾏多个任务。并⾏解决的是所谓的计算密集型问题,即通过把任务分成多个部分,并在多
个处理器上执⾏,从⽽提升程序运⾏的速度。纯并发(purely concurrent):多个任务在单CPU上运⾏。纯粹并发系统会⽐时序系统更快地⽣成结果(遇到阻塞可以执⾏其它任务),但是⽆法利⽤多处理器进⼀步提升性能。
并发式并⾏(concurrent-parallel):应⽤并发技术,使程序能利⽤多处理器并更快的产⽣结果。
并⾏式并发(parallel-concurrent):使⽤并⾏编程技术编写的程序,⽽且即便只有⼀个处理器也能运⾏(Java8的Stream就是很好的例⼦)。
纯并⾏(purely parallel):只能在多处理器上运⾏。

并发是⼀系列聚集于如何减少等待并提升性能的技术。

创建线程

继承Tread类创建线程

新建一个类Mythread继承Tread,重写run方法

public class Mythread extends Thread{//Tread类是Java中创建线程的类
    private final String name;

    public Mythread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        //任意代码,此线程单独执行的代码
        for (int i = 0; i < 10; i++) {
            IO.println(name + ":"+i);
        }

    }
}

New一个Mythread的对象,使用run方法创建线程

void main(){
    //t1才是可以执行任务的线程
    Mythread t1 = new Mythread("线程1");
    t1.start();//启动这个线程

    Mythread t2 = new Mythread("线程2");
    t2.start();

}

运行结果:时间片用尽会切换线程

D:\Java\Java25\bin\java.exe "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2025.3.3\lib\idea_rt.jar=12910" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath D:\Desktop\Study\Study\out\production\Study;C:\Users\Lenovo\.m2\repository\junit\junit\4.13.1\junit-4.13.1.jar;C:\Users\Lenovo\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar Main
线程1:0
线程2:0
线程1:1
线程2:1
线程1:2
线程2:2
线程1:3
线程2:3
线程1:4
线程2:4
线程1:5
线程2:5
线程1:6
线程2:6
线程1:7
线程2:7
线程1:8
线程2:8
线程1:9
线程2:9

另外注意启动线程是需要时间的,线程的切换时间完全无法预料且无法介入

例如在Main.java中直接敲入代码(在New对象实t1和t2下面)

//main线程
    for (int i = 0; i < 10; i++) {
        System.out.println("你好");
    }

则运行结果:

你好
你好
你好
你好
你好
你好
你好
你好
你好
你好
线程1:0
线程1:1
线程1:2
线程1:3
线程1:4
线程1:5
线程1:6
线程1:7
线程2:0
线程2:1
线程2:2
线程2:3
线程2:4
线程2:5
线程2:6
线程2:7
线程2:8
线程1:8
线程2:9
线程1:9

原因为线程启动需要时间,在这段时间内main线程已经跑完了,如果扩大main线程中for循环的次数,则有可能交叉运行。

实现Runnable接⼝

新建一个Teacher类,实现Runnable接口

public class Teacher implements Runnable{
    @Override
    public void run() {
        //在此处写执行的操作
        for (int i = 0; i < 10; i++) {
            IO.println("Teacher:" + i);
        }
    }
}

新建一个CounterTask类,实现Runnable接口

package cn.tinsur.lianxi.st2;

public class CounterTask implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            IO.println("我数到"+ i +"了");
        }
    }
}

实现新建线程

public class Main2 {
    static void main() {
        Teacher task = new Teacher();//这是一个任务对象
        Thread t1 = new Thread(task);//将任务作为线程构造器的参数,t1即线程对象
        t1.start();

        Thread t2 = new Thread(new CounterTask());
        t2.start();

        //main线程
        for (int i = 0; i < 20; i++) {
            IO.println("main线程执行"+i);
        }
    }
}

其中,new Teacher类和new CounterTask类只是新建一个任务,并不算新建线程,新建线程还需要将任务作为线程构造器参数,new线程对象

使用线程对象的start方法启动线程

⽤Callable创建线程(注重结果)

和Runnable的异同:

都是一个任务

Runnable的任务只负责执行不负责返回

Callable可以返回一个值

新建一个SumTask类,实现Callable接口,用于计算和,注意添加泛型(泛型是返回值的类型),并重写Call方法:

Callable是有泛型的,该泛型是返回值类型

import java.util.concurrent.Callable;
//也是一个任务
public class SumTask implements Callable<Long> {//Callable是有泛型的,该泛型是返回值类型

    @Override
    public Long call() throws Exception {
        long sum = 0L;
        for (int i = 0; i < 1000000; i++) {
            sum += i;
        }
        return sum;
    }
}

新建线程方法:

 
public class Main3 {
    static void main() throws ExecutionException, InterruptedException {
        SumTask st = new SumTask();
        FutureTask<Long> ft = new FutureTask<>(st);//一个在未来可以返回值的任务
        Thread t = new Thread(ft);//把未来返回值的任务作为参数来创建对象
        t.start();//启动线程

    }

}

检测线程是否完成:

IO.println(ft.isDone());//检测线程是否完成了

获取线程执行结果,该方法会阻塞进程

IO.println(ft.get());//获取任务执行的结果,需要捕获异常,会阻塞等待

至此,共三种创建线程的方法:直接继承Thread类、实现Runnable接口、实现Callable接口

THE END
文章版权归Tinsur.cn所有,不允许任何形式的转载
点赞1 分享