zoukankan      html  css  js  c++  java
  • Java创建线程的四种方式

    Java创建线程的四种方式

    1.继承Thread类创建线程

    • 定义Thread类的子类,并重写该类的run方法,run()方法的内容就是该线程执行的内容
    • 创建Thread子类的实例,即创建了线程对象。
    • 调用线程对象的start()方法来启动该线程。
      代码演示
    public class MyThread extends Thread {
    
        @Override
        public void run() {
            // 执行业务逻辑
        }
    
        public static void main(String[] args) {
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }
    

    2.通过Runnable接口创建线程类

    • 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
    • 创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
    • 调用线程对象的start()方法来启动该线程。
      代码演示
    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            // 执行业务逻辑
        }
        
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
            Thread thread = new Thread(myRunnable);
            thread.start();
        }
    }
    

    3.使用Callable接口和FutureTask类实现创建有返回结果的线程

    FutureTask 的出现是为了弥补 Thread 的不足而设计的,可以让程序员跟踪、获取任务的执行情况、计算结果

    • 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
    • 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对- 象的call()方法的返回值。
    • 使用FutureTask对象作为Thread对象的target创建并启动新线程。
    • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
      代码演示
    public class MyCallable implements Callable<Integer>{
        @Override
        public Integer call() throws Exception {
            System.out.println("子线程开始计算");
            Thread.sleep(2000);
            System.out.println("子线程结束计算");
            return 100 * 100;
        }
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 实例化Callable对象
            MyCallable myCallable = new MyCallable();
            // 使用FutureTask包装
            FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
            // 创建一个线程执行任务
            Thread thread = new Thread(futureTask);
            thread.start();
            Thread.sleep(1000);
            System.out.println("主线程执行");
            // 使用get()方法会阻塞主线程,直到子线程执行完成返回结果
            int result = futureTask.get();
            System.out.println("子线程计算结果: " + result);
        }
    
    }
    

    执行结果

    子线程开始计算
    主线程执行
    子线程结束计算
    子线程计算结果: 10000
    

    4.使用线程池创建线程

    为什么要使用线程池呢?
    当不是执行一次性任务的时候,如果不使用线程池,那么就要频繁的创建和销毁线程,这是一个比较消耗资源的操作,使用线程池可以灵活的调整线程资源的占用,防止消耗过多的内存
    在Java中已经提供了ExecutorSerice、Executors等工具类为我们快速的创建线程池
    常用的常见线程的方法有

    • Executors.newFixedThreadPool(int nThreads) --- 创建固定线程数量的线程池
    • Executors.newSingleThreadPool() --- 创建只包含一个线程的线程池
    • Executors.newCachedThreadPool() --- 创建一个可缓存的线程池。如果线程池的当前规模超过了处理需求时,那么就会回收部分空闲的线程(根据空闲时间来回收),当需求增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
    • Executors.newScheduledThreadPool() --- 创建了一个固定长度的线程池,而且以延迟或定时或周期的方式来执行任务,类似于Timer。可应用于重发机制。
  • 相关阅读:
    Designing IP-Based Video Conferencing Systems: Dealing with Lip Synchronization(唇音同步)
    ffmpeg 如何音视频同步
    音视频同步(播放)原理
    您的 PHP 似乎没有安装运行 WordPress 所必需的 MySQL 扩展”处理方法
    ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statemen
    获得H.264视频分辨率的方法
    1080P、720P、4CIF、CIF所需要的理论带宽
    linux mysql 操作命令
    RTP/RTCP的时间同步机制
  • 原文地址:https://www.cnblogs.com/xiguadadage/p/11818704.html
Copyright © 2011-2022 走看看