zoukankan      html  css  js  c++  java
  • Java多线程入门(二)——多线程的创建方式

        多线程的创建有以下三种方式:

    1. 继承Thread类,重写run方法
    2. 实现Runnable接口,重写run方法
    3. 匿名内部类

           其实还可以使用JDK1.5之后的Callable类和线程池的方式创建,但是该系列只是Java多线程入门,而且我也对线程池的使用不是很了解,所以就没有写它们了。但是好像上面的这些方式都用的不多,都是使用线程池创建线程。(哈哈,只能怪自己太菜,菜是原罪啊,还得继续加油,欧力给)

    1、继承Thread类

        使用Thread类创建线程的步骤:

    1. 创建一个继承自Thread类的子类。
    2. 重写Thread类的run()方。
    3. 创建Thread类的子类对象。
    4. 通过子类对象调用start()方法。
    package com.thr;
    
    /**
     * @author Administrator
     * @date 2020-03-13
     * @desc 继承Thread类
     */
    
    //1、创建一个继承自Thread类的子类
    class MyThread extends Thread{
        //2、重写Thread类的run()方法
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    public class ThreadDemo {
        public static void main(String[] args) {
            //3、创建Thread类的子类对象
            MyThread t1 = new MyThread();
            MyThread t2 = new MyThread();
    
            //4、通过子类对象调用start()方法
            t1.start();
            t2.start();
        }
    }

    运行结果如下:

    image

           从上面的运行结果可以看出:线程是一个子任务,创建的线程是交替执行的。这是线程调度的结果,Java的线程调度策略是优先级抢占式调度,首先让优先级高的线程大概率能够使用CPU资源,如果线程的优先级相同,那么CPU会随机调度(线程随机性),上面的代码都是默认的优先级,创建的两个线程同时在抢占CPU的资源,那么谁能抢占到的CPU资源就执行。所以输出的结果是随机的,我们是不能干涉的。

       注意:不要将run()和start()这两者给搞混了。

       run()和start()方法区别:

    • start():首先启动当前线程,然后再由JVM去调用该线程的run()方法。
    • run():仅仅是封装被线程执行的代码,直接调用是普通方法,并不会启动线程。

    还有需要注意一点的是:如果该线程已经调用了start()方法,则不能再次调用该方法了,否则会抛出IllegalThreadStateException异常。解决办法就是重新创建一个Thread子类的实例调用start()方法。

    2、实现Runnable接口

       使用Runnable接口创建线程的步骤:

    1. 创建一个实现Runnable接口的类。
    2. 实现类去实现Runnable接口中的抽象方法run()。
    3. 创建实现类的对象。
    4. 创建一个Thread类,将实现类的对象传入到Thread类的构造器中。
    5. 通过Thread类的对象调用start()方法。
    package com.thr;
    
    /**
     * @author Administrator
     * @date 2020-03-13
     * @desc 实现Runnable接口
     */
    //1、创建一个实现了Runnable接口的类
    class MyThread implements Runnable{
        //2、实现Runnable接口的抽象run()方法
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    public class RunnableDemo {
        public static void main(String[] args) {
            //3、创建实现类对象
            MyThread m = new MyThread();
            //4、创建一个Thread类,将实现类的对象传入到Thread类的构造器中。
            Thread t1 = new Thread(m);
            Thread t2 = new Thread(m);
            //5、通过Thread类的对象调用start()方法。
            t1.start();
            t2.start();
        }
    
    }
    

    既然有这两种方式实现对线程,那么我们使用哪一种呢???

    答:一般使用的是实现Runnable接口方式开发多线程,因为Java只能单继承却可以实现多个接口。

    3、匿名内部类

       Thread匿名内部类

    package com.thr;
    
    /**
     * @author Administrator
     * @date 2020-03-13
     * @desc Thread类的匿名内部方式
     */
    
    public class ThreadDemo {
        public static void main(String[] args) {
    
            //创建一个打印1000以内的所有偶数的线程
            new Thread(){
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        if (i % 2 == 0){
                            System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }.start();
    
            //创建一个打印1000以内的所有奇数的线程
            new Thread(){
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        if (i % 2 != 0){
                            System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }.start();
        }
    }

       Runnable作为参数传入Thread类的匿名内部方式。

    package com.thr;
    
    /**
     * @author Administrator
     * @date 2020-03-13
     * @desc Runnable作为参数传入Thread类的匿名内部方式
     */
    
    public class RunnableDemo1 {
        public static void main(String[] args) {
            //创建一个打印1000以内的所有偶数的线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        if (i % 2 == 0){
                            System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }).start();
    
            //创建一个打印1000以内的所有奇数的线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 1000; i++) {
                        if (i % 2 != 0){
                            System.out.println(Thread.currentThread().getName()+":"+i);
                        }
                    }
                }
            }).start();
        }
    }
    
  • 相关阅读:
    FreeRTOS相关转载-(朱工的专栏)
    任务相关的API函数-uxTaskGetSystemState
    STM32用FreeRTOS时任务优先级和中断优先级说明
    STM32标准外设库中USE_STDPERIPH_DRIVER, STM32F10X_MD的含义
    C语言变量和函数命名规范
    Java学习笔记-命令模式
    leetcode-Search in Rotated Sorted Array -java
    Java学习笔记-单件模式
    Java学习笔记-问问题?-->静态方法
    TCP滑动控制
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/12470248.html
Copyright © 2011-2022 走看看