• javaSE——多线程


    并发与并行

    • 并发:指两个或多个事件在同一时间段内发生。(交替执行)
    • 并行:指两个或多个事件在同一时刻发生。(同时发生)

    进程与线程

    (线程<进程)

    • 进程:程序的执行过程。(可在任务管理器查看)
    • 线程:进程中的一个执行单元。

    一个程序运行后至少有一个进程,一个进程中可以包含多个线程。

    线程一定得依附于进程才能够存在。

    线程调度

    (1)分时调度:
    所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间。
    (2)抢占式调度:
    优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)。java使用的为抢占式调度。

    时间片:每一个任务每次在CPU中占有的时间

    多线程的实现

    1.继承Thread

    Thread是操作线程的类,任何类只需要继承Thread类就可以成为一个线程的主类。

    Thread类下的两个重要方法:
    run()和start()方法。
    线程执行体:run()。(线程需要完成的任务)
    线程的起点:start()。(线程的启动,启动后执行的方法体是run()方法定义的代码)
    程序的起点:main()。

    public class TestThread {
        public static void main(String[] args) throws InterruptedException {
            MyThread myThread = new MyThread("张三");
            MyThread myThread02 = new MyThread("李四");
            // 调用start方法
            myThread.start();
            myThread02.start();
    
    //        // 获取线程名称
    //        System.out.println(myThread.getName());
    //        System.out.println(myThread.getId());
    //        System.out.println(myThread.getPriority());
    //        System.out.println(Thread.currentThread().getPriority());
    //        System.out.println(myThread.getState());
    //        myThread.interrupt();
            // 是否活着
    //        myThread.isAlive();
    //        myThread.stop();
    
            // join 会阻塞当前线程(主线程)
    //        myThread.join();
    
            Thread.currentThread().setName("主函数");
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() +"主线程也在运行"+ i);
            }
    
            // 暗示当前线程放弃一次抢占
            Thread.yield();
    
        }
    }
    
    // java的线程类
    class MyThread extends Thread {
    
        public MyThread(){}
    
        public MyThread(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            // 要执行的代码写在这儿
            for (int i = 0; i < 10; i++) {
                if (i == 5) {
                    try {
                        // 让线程进入休眠状态
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() +"一个独立的子线程运行了"+ i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    在这里插入图片描述

    2.实现Runnable接口

    为了避免单继承局限的问题,我们可以使用Runnable接口来实现多线程。
    要启动多线程,就一定需要通过Thread类中的start()方法,但是Runnable接口中没有提供可以被继承的start()方法。这时就需要借住Thread类中提供的有参构造方法

    好处:

    1. 避免单继承局限;
    2. 降低程序的耦合性,方便解耦。即把设置线程任务(实现类中重写run())和开启新线程(Thread类对象调用start())进行了分离。
    public class TestThread04 implements Runnable {
    
        private int count;
        
        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                count++;
            }
            System.out.println(Thread.currentThread().getName() + "count = " + count);
        }
    
        public static void main(String[] args) {
            TestThread04 task = new TestThread04();
            new Thread(task).start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    3.实现Callable接口

    实现Callable为JDK5新增功能,和实现Runnable相比,借助FutureTask类可以实现更加强大的功能,使用起来更加灵活:

    • 相比run方法,call方法可以有返回值。
    • 方法可以抛出异常。
    • 支持泛型的返回值。
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class TestCallable {
        public static void main(String[] args) {
            MyThread2 mt = new MyThread2();
            FutureTask futureTask = new FutureTask(mt);
            new Thread(futureTask).start();
    
            // 使用callable接口实现的多线程对象,最后能够得到线程方法返回的结果
            try {
                Integer res = (Integer) futureTask.get();
                System.out.println("线程方法返回的结果:" +res);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() +"主线程开始运行");
            }
    
        }
    }
    
    class MyThread2 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                sum += i;
                System.out.println("使用Callable接口创建的子线程"+ i);
            }
            return sum;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

  • 相关阅读:
    JavaWeb-05 jQuery
    2022年苹果审核4.3相关问题总结
    Abbexa人猴痘病毒IgM (MPXV IgM) ELISA试剂盒
    网络编程常用的几种字符编码
    磁盘原理简要分析
    UE5.1编辑器拓展【三、脚本化资产行为,删除无引用资产】
    Mybatis save、saveOrUpdate、update的区别
    Sanitizers 系列之 leak sanitizer 介绍
    《Mybatis 手撸专栏》第9章:细化XML语句构建器,完善静态SQL解析
    一体化HIS医疗信息管理系统源码:云HIS、云电子病历、云LIS
  • 原文地址:https://blog.csdn.net/Demon_and_Angle_/article/details/126389807