• 【第八章 多线程、并行并发、多线程的创建方式】


    第八章 多线程、并行并发、多线程的创建方式(继承Thread类和实现Runnable接口)

    1.程序、进程、线程
    ①程序:是为完成特定任务,用某种语言编写的一组指令的集合。即一段静态的代码,静态对象。
    ②进程:是程序的一次执行过程,或是正在运行中的一个程序。是一个动态的过程,有它自身的产生,存在,消亡的过程。
    ③线程:进程可进一步细化为线程,是一个程序内部的一条执行路径
    a.若一个进程同时并行执行多个线程,就是支持多线程的。
    b.线程作为调度和执行的最小单位,每个线程都拥有独立的运行栈和程序计数器,线程切换的开销小。
    c.一个进程中的多个线程共享相同的内存单元/内存地址空间—>它们从一堆中分配对象,可以访问相同的变量和对象,这使得线程直接通信更简洁高效,但多个线程操作共享的系统资源可能就会带来安全隐患。
    2.并行、并发
    ①并行:多个CPU执行多个任务、比如:多人同时做不同的事。
    ②并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀,多人做同一件事。
    3.多线程的创建方式一:继承于Thread类
    ①创建一个继承于Thread类的子类;
    ②重写Thread类的run()---->将此线程执行的操作声明在run中;
    ③创建Thread类的子类的对象;
    ④通过此对象调用start()。
    (1)不能通过直接调用run()的方式启动线程 t1.run()
    (2)再启动一个线程遍历一百以内的偶数,不可以还让已经start的线程去执行,会报异常;需要重写创建一个线程的对象,去start。

    package day8;
    // 多线程的创建:方式一:继承于hread
    //1.创建一个继承于Thread类的子类
    class MyThread extends Thread{
        //2.重写Thread类的run()
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                if(i%2==0){      System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        }
    }
    public class ThreadTest {
        public static void main(String[] args) {
            //3.创建Thread类的子类的对象
            MyThread t1 = new MyThread();
            MyThread t2 = new MyThread();
            //4.通过此对象调用start():
            //①启动当前线程;②调用当前线程的run()
            t1.start();
            t2.start();
            //如下的操作仍然是在main线程中执行的
            for(int i=0;i<100;i++){
                if(i%2==0){   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

    4.多线程的创建方式二:实现Runnable接口
    ①创建一个实现了Runnable接口的类;
    ②实现类去实现Runnable中的抽象方法:run();
    ③创建实现类的对象;
    ④将此对象作为参数传递到Thread类的构造器中,创建Thread的对象;
    ⑤通过Thread类的对象调用start()。

    //1.创建一个实现了Runnable接口的类
    class MThread implements Runnable{
        //2.实现类去实现Runnable中的抽象方法:run()
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                if (i % 2 == 0) {
                    System.out.println(i);
                }
            }
        }
    }
    public class ThreadTest1 {
        public static void main(String[] args) {
            //3.创建实现类的对象
            MThread mThread = new MThread();
         //4.将此对象作为参数传递到Thread类的构造器中,创建Thread的对象
            Thread t1 = new Thread(mThread);
            //5.通过Thread类的对象调用start()
       //①启动线程;②调用当前线程的run()--->调用了Runnable类型的target
            t1.start();
            //再启动一个线程
            Thread t2 = new Thread(mThread);
            t2.start();
        }
    }
    
    • 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

    5.比较创建多线程的两种方式
    开发中优先选择实现Runnable接口的方式。
    (1)原因:①实现的方式没有类的单继承性的局限性;
    ②实现的方式更适合处理多个线程有共享数据的情况。
    (2)联系:①Thread类本身也实现Runnable接口;
    ②两种方式都要重写run(),将线程要执行的逻辑声明在run()中。
    6. 练习:创建两个分线程,其中一个线程去遍历100以内的偶数,另一个线程去遍历100以内的奇数

    package day8;
    //方式一:创建两个线程分别执行
    public class ThreadDemo {
        public static void main(String[] args) {
            MyThread1 m1 = new MyThread1();
            MyThread1 m2 = new MyThread1();
            m1.start();
            m2.start();}
    }
    class  MyThread1 extends  Thread{
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                if(i%2==0) {    System.out.println(Thread.currentThread().getName()+":"+i);
                }
            }
        }
    }
    class  MyThread2 extends  Thread{
        @Override
        public void run() {
            for(int i=0;i<100;i++){
                if(i%2!=0) {          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
    //方式二:创建Thread类的匿名子类的方式
    public class ThreadDemo {
        public static void main(String[] args) {
            new Thread(){
                @Override
                public void run() {
                    for(int i=0;i<100;i++){
                        if(i%2==0) {                       System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }.start();
            new Thread(){
                @Override
                public void run() {
                    for(int i=0;i<100;i++){
                        if(i%2!=0) {                    System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }.start();
        }
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    Postman-Installation has failed
    【计算机毕业设计】7.线上花店系统maven源码
    基于simulink的单相光伏系统并网储能控制仿真
    阴影(shadow mapping)(硬阴影)
    Maven高级
    Fourier分析导论——第3章——Fourier级数的收敛性(E.M. Stein & R. Shakarchi)
    使用 webpack-cli 零配置打包,真香
    友情提示:lazarus的tsortgrid.autofillcolumns存在BUG
    RabbitMQ的基本使用
    性能分析优化的道与术
  • 原文地址:https://blog.csdn.net/qq_43742813/article/details/126818845