多线程详解 创建多线程

2022年8月5日10:15:45

一. 进程与线程:

1. 进程:

进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

2. 线程:

线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

3. 执行方式:

① 顺序执行:即程序从上往下一步一步的执行
② 并发执行:指两个或多个事件在同一个时间段内执行
③ 并行执行:指两个或多个事件在同一时刻同时执行

二. 创建多线程的三种方式:

1. 继承Thread类:

继承Thread类后要重写Thread类的run()方法,然后调用start()方法开启线程

public class TestThread1 extends Thread{
    public static void main(String[] args){
        EatThread eatThread= new EatThread();
        DrinkThread drinkThread= new DrinkThread();
        eatThread.start();
        drinkThread.start();}}

class EatThread extends Thread{
    @Override
    public void run(){
        System.out.println("开始吃饭?...\t" + new Date());
        try{
            Thread.sleep(5000);} catch(InterruptedException e){
            e.printStackTrace();}
        System.out.println("结束吃饭?...\t" + new Date());}}

class DrinkThread extends Thread{
    @Override
    public void run(){
        System.out.println("开始喝酒?...\t" + new Date());
        try{
            Thread.sleep(5000);} catch(InterruptedException e){
            e.printStackTrace();}
        System.out.println("结束喝酒?...\t" + new Date());}}

此时的运行结果为:
多线程详解 创建多线程
当把主函数(即主线程)改为run()方法开启线程:

public class TestThread1 extends Thread{
    public static void main(String[] args){
        EatThread eatThread= new EatThread();
        DrinkThread drinkThread= new DrinkThread();
        eatThread.run();
        drinkThread.run();}}

此时的运行结果为:
多线程详解 创建多线程
造成区别的原因时:当使用start()方法开启线程时,各线程是并发执行的,当使用run()方法开启线程时,各线程是顺序执行的。
多线程详解 创建多线程

2. 实现Runnable接口:

与继承Thread类方法类似,实现Runnable接口后要重写run()方法,然后使用Thread类来包装调用start()方法开启线程

public class TestThread2 implements Runnable{
    @Override
    public void run(){
        System.out.println("开始吃饭?...\t" + new Date());
        try{
            Thread.sleep(5000);} catch(InterruptedException e){
            e.printStackTrace();}
        System.out.println("结束吃饭?...\t" + new Date());}

    public static void main(String[] args){
        TestThread2 t1= new TestThread2();
        new Thread(t1).start();
        Thread thread= new Thread(t1);  //对同一对象进行多线程从操作
        thread.start();}}

运行结果为:
多线程详解 创建多线程

注意:newThread(t1).start();Threadthread=newThread(t1);thread.start();这两种写法效果是一样的第一种方法继承Thread类,Thread类也实现了Runnable接口第二种方法实现Runnable接口,类似创建一个代理工具类推荐使用实现Runnable接口的方法实现多线程,可以避免Java单线程的限制线程开启不一定立即执行,由CPU调度执行

3. 实现Callable接口:

① 实现Callable接口,需要返回值类型
② 重写call()方法,需要抛出异常
③ 创建目标对象 : TestThread3 testThread3 = new TestThread3()
④ 创建执行服务 : ExecutorService ser = Executors.newFixedThreadPool(2)
⑤ 提交执行 : Future r1 = ser.submit(testThread3)
⑥ 获取结果 : boolean rst1 = r1.get();
⑦ 关闭服务 : ser.shutdownNow();

public class TestThread3 implements Callable<Boolean>{  //①实现Callable接口,需要返回值类型
    private String name;

    public TestThread3(String name){
        this.name= name;}
    @Override
    public Boolean call() throws Exception{  //②重写call()方法,需要抛出异常
        if(name.equals("张三")){
            System.out.println("欢迎"+name);returntrue;}returnfalse;}

    public static void main(String[] args) throws ExecutionException, InterruptedException{
        //③创建目标对象
        TestThread3 t1= new TestThread3("张三");
        TestThread3 t2= new TestThread3("李四");

        //④创建执行服务
        ExecutorService ser= Executors.newFixedThreadPool(2);

        //⑤提交执行
        Future<Boolean> r1= ser.submit(t1);
        Future<Boolean> r2= ser.submit(t2);

        //⑥获取结果
        boolean rst1= r1.get();
        boolean rst2= r2.get();
        System.out.println(rst1);
        System.out.println(rst2);

        //⑦关闭服务
        ser.shutdownNow();}}

运行结果:
多线程详解 创建多线程

三. 多线程实例——龟兔赛跑

public class Race implements Runnable{
    private static String winner;
    @Override
    public void run(){for(int i= 1; i<= 100; i++){
            // 模拟兔子休息
            if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
                try{
                    Thread.sleep(100);} catch(InterruptedException e){
                    e.printStackTrace();}}

            boolean flag= isGameOver(i);
            // 如果比赛结束,终止程序if(flag){break;}
            // Thread.currentThread()获取当前线程
            // Thread.currentThread().getName()获取当前线程名字
            System.out.print(Thread.currentThread().getName()+"-->跑了"+i+"步"+"\t");
            if(i%5==0)
                System.out.println();}}
    // 判断是否有胜利者
    public boolean isGameOver(int step){if(winner!=null){returntrue;}else{if(step>=100){
                winner= Thread.currentThread().getName();
                System.out.println("winner is "+winner);returntrue;}}returnfalse;}

    public static void main(String[] args){
        Race race= new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();}}

结果:
多线程详解 创建多线程
参考:https://blog.csdn.net/vbirdbest/article/details/81282163.

  • 作者:流水伊旧
  • 原文链接:https://blog.csdn.net/weixin_43912697/article/details/113850845
    更新时间:2022年8月5日10:15:45 ,共 3806 字。