• (1)多线程-线程的创建


    继承Thread

    通过继承Thread类来创建并启动多线程的一般步骤:

    • 定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也成为线程执行体。
    • 创建Thread子类的实例,也就是创建了线程对象
    • 启动线程,即调用线程的start()方法
    public class MyThread extends Thread {
    
        @Override
        public void run() {
            System.out.println("使用继承Thread方式创建线程");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class TestThread {
    
        public static void main(String[] args) {
            System.out.println("JVM 启动 main 线程,main 线程执行 main 方法");
            MyThread thread = new MyThread();
            thread.start();
            /**
             * 调用线程的 start()方法来启动线程, 启动线程的实质就是请求 JVM 运行相应的 线程,这个线程具体在什么时候运行由线程调度器(Scheduler)决定
             * 注意:
             * start()方法调用结束并不意味着子线程开始运行
             * 新开启的线程会执行 run()方法
             * 如果开启了多个线程,start()调用的顺序并不一定就是线程启动的顺序
             * 多线程运行结果与代码执行顺序或调用顺序无关
             */
            System.out.println("main 线程后面其他 的代码...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    实现Runnable接口创建线程

    通过实现Runnable接口创建并启动线程一般步骤如下:

    • 定义Runnable接口的实现类,一样要重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体
    • 创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象
    • 第三部依然是通过调用线程对象的start()方法来启动线程
    public class MyRunnable implements Runnable {
    
        @Override
        public void run() {
            System.out.println("使用实现Runnable接口方式创建线程");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class TestThread {
    
        public static void main(String[] args) {
            System.out.println("JVM 启动 main 线程,main 线程执行 main 方法");
            MyRunnable runnable = new MyRunnable();
            Thread thread = new Thread(runnable);
            thread.start();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实现Callable和Future接口创建线程

    和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。call()方法可以有返回值call()方法可以声明抛出异常Java5提供了Future接口来代表Callable接口里call()方法的返回值,并且为Future接口提供了一个实现类FutureTask,这个实现类既实现了Future接口,还实现了Runnable接口,因此可以作为Thread类的target。在Future接口里定义了几个公共方法来控制它关联的Callable任务。

    • 创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。
    • 使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值
    • 使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)
    • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
    public class MyCallable implements Callable {
        @Override
        public Object call() throws Exception {
            System.out.println("使用实现Callable接口方式创建线程");
            return 10;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class TestThread {
    
        public static void main(String[] args) {
            System.out.println("JVM 启动 main 线程,main 线程执行 main 方法");
            MyCallable callable = new MyCallable();
            FutureTask futureTask = new FutureTask<>(callable);
            new Thread(futureTask).start();
            try {
                System.out.println(futureTask.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    常见的海量数据面试题总结
    数据结构与算法【Java】02---链表
    存储器和CPU的连接与TCP的流量控制
    用Java方法来打印从1到N的阶乘的和
    C# newtonsoft对json进行排序
    【Debug】NI VISA VI_ERROR_NLISTENERS
    hive 基础知识
    UDS诊断测试
    Qt的环境变量处理与程序发布之间的关系
    PysparkNote103---window滑窗
  • 原文地址:https://blog.csdn.net/baidu_41634343/article/details/126819535