实现多线程的3种方式

  • 并发和并行
  • 继承Thread类
  • 实现Rannble接口
  • 利用Callable接口和Future接口

一段程序的运行过程是一个进程,而一个过程可以由多个线程组成。例如一个软件的运行是一个进程,而软件中的各种功能可以认为是构成进程的多个线程

在以前我们的单线程程序中,我们的代码在运行的时候会和内存进行交互,此时我们的CPU就只能进行等待,而在多线程的程序中我们的CPU在空闲的时间回去执行别的线程的程序而不会去等待,提高了对CPU的利用率

并发和并行


1个CPU交替执行多条线程


2个线程在2个CPU上同时执行

实际上我们的电脑并不是只能运行一个线程,根据CPU一次可以执行多少线程,可以有以下分类:

  • 并行

    当我们的2核4线程的CPU只有4条线程在执行时,此时是并行


当我们要执行的线程多余4条将会并发执行,将会在这些线程中随机切换执行。即并发执行所以说在我们计算机中并发和并行其实都存在

第一种实现--继承Thread类

Thread类表示线程,当我们的类继承自Tread即可以表现出多线程。要求实现Thread类的run方法,线程将执行run方法中的内容,必须要使用start方法启动线程

package com.cook.test;

public class MyThread1   extends Thread{
    public MyThread1(){};
    public MyThread1(String threadname){
        super(threadname);
    }
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(this.getName()+"hello world!");
        }
    }
}

package com.cook.test;

public class MyThreadTest1 {
    public static void main(String[] args) {
       MyThread1 t1 = new MyThread1();
       MyThread1 t2 = new MyThread1();
       t1.start();
       t2.start();

    }
}

其实这里有3个线程抢夺CPU资源,main方法也是一个线程。从输出可以看出t1 t2这2给线程争夺CPU的情况

实现Runnable接口

其实继承Thread类实现多线程有一个弊端,因为如果一个类继承了Thread类将不能实现别的类,这将会到来极大的局限性,可以用实现Runnalb的方式来破冰

package com.cook.test;

public class MyThread2 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"hello world");
        }
    }
}

package com.cook.test;

public class MyThreadTest2 {
    public static void main(String[] args) {
        MyThread2 t = new MyThread2();
        Thread t1 = new Thread(t,"线程1");//要在Thread中传入我们实现了Rannable的对象(可传入线程名)
        Thread t2 = new Thread(t,"线程2");//要在Thread中传入我们实现了Rannable的对象
        t1.start();
        t2.start();
    }
}

利用Callable接口和Future接口

前面的方式解决了只能实现Thread不能有别的接口的问题,但是我们的run方法没有返回值,我们有些时候是需要run方法的返回值的

package com.thread.case1;

import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {//泛型表示线程要返回的类型
    @Override
    public Integer call() throws Exception {//这个相当于run方法里面写执行多线程的代码
        //计算1-100的和
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            sum+=i;
        }
        return sum;
    }
}


package com.thread.case1;

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

public class ThreadTest3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

       /* 多线程第三种实现:可以获取多线程的运行结果
        1.创建一个类MyCallable实现Callable接口
        2.重写call(是有返回值的,表示多线程的运行结果)
        3.创建MyCallable的对象(表示多线程要执行的任务)
         4.创建FutureTask的对象(作用管理多线程运行的结果)
         5.创建Thread类的对象,并启动线程*/
       MyCallable ma = new MyCallable();
        FutureTask<Integer> ft = new FutureTask<>(ma);
        Thread td = new Thread(ft);
        td.start();
        final Integer result = ft.get();//获取线程的值
        System.out.println(result);

    }
}


posted @ 2023-03-07 19:05  一往而深,  阅读(155)  评论(0编辑  收藏  举报