Java实现线程的四种方式解析

 更新时间:2023年10月18日 09:16:18   作者:喜上编程  
这篇文章主要介绍了Java实现线程的四种方式解析,线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序,需要的朋友可以参考下

概念

进程

进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能

线程

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序

程序

程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。

主线程

jvm启动后,必然有一个执行路径(线程)从main方法开始的,一直执行到main方法结束,这个线程在java中称之为主线程。

进程调度策略

java主要用的是抢占式调度 进程调度的方式参考进程调度策略

创建线程的方法(四种)

1.匿名代码块

package com.it.threads;
public class Demo2 {
    public static void main(String[] args) {
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i <1000 ; i++) {
      System.out.println(Thread.currentThread().getName()+"---===>"+i);
                }
            }
        }.start();
        System.out.println("-----------main over--------------");
    }
}

2.继承Thread类

package com.it.threads;

/**
 * 创建线程的步骤: 1 定义一个类继承 Thread。
 * 2 重写 run 方法。
 * 3 创建子类对象,就是创建线程对象。
 * 4 调用 start 方法,开启线程并让线程执行,
 * 同时还会告诉 jvm 去调用 run 方法。
 * @version: $
 */
public class ThreadA extends Thread {
    /**
     * 线程的任务写在run方法中
     */
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName() + "-->" + i);
        }
    }
    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        //设置线程的名字
        threadA.setName("得力");
        threadA.setPriority(10);
        //设置线程的优先级
        ThreadA threadA1 = new ThreadA();
        //设置线程的名字
        threadA1.setName("得力1");
        threadA1.setPriority(Thread.MIN_PRIORITY);
        threadA1.start();
        threadA.start();
        System.out.println(threadA.getPriority());
        System.out.println(threadA1.getPriority());
    }
}

3.实现Runnable接口

package com.it.threads;
/**
 * 1、定义类实现 Runnable 接口。
 * 2、覆盖接口中的 run 方法。。
 * 3、创建 Thread 类的对象
 * 4、将 Runnable 接口的子类对象作为参数传递给 Thread 类的构造函数。
 * 5、调用 Thread 类的 start 方法开启线程。
 * @version:     $
 */
public class ThreadB implements  Runnable {
    @Override
    public void run() {
        for (int i = 0; i <1000 ; i++) {
            System.out.println(Thread.currentThread().getName()+"---->"+i);
        }
    }
    public static void main(String[] args) {
        ThreadB threadB = new ThreadB();
        Thread thread1 = new Thread(threadB,"aa");
        Thread thread2 = new Thread(threadB,"bb1");
        //启动线程
        thread1.start();
        thread2.start();
    }
}

4.线程池

线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。 实现线程池分为两种

(1)实现Runnable

创建一个线程

package com.it.threadpool;
//方式一    实现Runnable接口
public class ThreadRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i <2; i++) {
           System.out.println(Thread.currentThread().getName()+i+"进入电影院");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+i+"离开电影院");
        }
    }
}

创建线程池

package com.it.threadpool;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/*
* 创建线程池对象
创建Runnable接口子类对象
提交Runnable接口子类对象
关闭线程池
* */
public class ThreadRunnablePool {
    public static void main(String[] args) {
        //创建线程池对象 线程个数  Executors:线程池创建工厂类  ExecutorService:线程池类
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //创建Runnable实例对象
        ThreadRunnable threadRunnable = new ThreadRunnable();
        //从线程池中获取线程对象,然后调用run()
        executorService.submit(threadRunnable);
        executorService.submit(threadRunnable);
        executorService.submit(threadRunnable);
        executorService.shutdown();
    }
}

(2)实现Callable接口

创建线程

package com.it.threadpool;

import java.util.concurrent.Callable;

public class ThreadCallable implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("我要一个教练:call");
        Thread.sleep(2000);
        System.out.println("教练来了: " +Thread.currentThread().getName());
        System.out.println("教我游泳,交完后,教练回到了游泳池");
        return null;
    }
}

创建线程池

package com.it.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadCallablePool {
    public static void main(String[] args) {
        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(2);
        //生成Callable对象
        ThreadCallable threadCallable=new ThreadCallable();
        //从线程池中获取线程对象,然后调用run()
        service.submit(threadCallable);
        service.submit(threadCallable);
        service.submit(threadCallable);
        service.shutdown();
    }
}

这两种方式的区别如下:

  • Callable定义的方法是call,而Runnable定义的方法是run。
  • Callable的call方法可以有返回值,而Runnable的run方法不能有返回值,这是核心区别。
  • Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。

举一个例子说明 创建一个线程用来求和

package com.it.threadpool;
import java.util.concurrent.Callable;
public class ThreadSum implements Callable<Integer> {
    int x;
    int y;
    public ThreadSum(int x, int y) {
        this.x = x;
        this.y = y;
    }
    @Override
    public Integer call() throws Exception {
        return x+y;
    }
}

创建线程池

package com.it.threadpool;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadSumPool {
    public static void main(String[] args) {
     ExecutorService executorService= Executors.newFixedThreadPool(5);
     //Future用来接收call方法的返回值
        Future future1=executorService.submit(new ThreadSum(200,500));
        Future future2=executorService.submit(new ThreadSum(100,500));
        Future future3= executorService.submit(new ThreadSum(200,600));
        try {
        //get()方法用来获取返回值
            System.out.println(future1.get());
            System.out.println(future2.get());
            System.out.println(future3.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

到此这篇关于Java实现线程的四种方式解析的文章就介绍到这了,更多相关Java实现线程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现世界上最快的排序算法Timsort的示例代码

    Java实现世界上最快的排序算法Timsort的示例代码

    Timsort 是一个混合、稳定的排序算法,简单来说就是归并排序和二分插入排序算法的混合体,号称世界上最好的排序算法。本文将详解Timsort算法是定义与实现,需要的可以参考一下
    2022-07-07
  • 分析Java中为什么String不可变

    分析Java中为什么String不可变

    Java中为什么String是不可变性的。今天我们从多角度解析为什么Java把String做成不可变的。
    2021-06-06
  • Mybatis 简单启动过程入门详解

    Mybatis 简单启动过程入门详解

    MyBatis是一个持久层框架,简化JDBC操作,SpringBoot集成MyBatis,通过创建项目、准备数据、配置文件、实体类和接口,可以实现数据库操作,使用@Mapper和@Select注解简化接口实现,测试类使用@SpringBootTest和@Test注解启动,本文介绍Mybatis启动过程,感兴趣的朋友一起看看吧
    2025-03-03
  • 如何利用postman完成JSON串的发送功能(springboot)

    如何利用postman完成JSON串的发送功能(springboot)

    这篇文章主要介绍了如何利用postman完成JSON串的发送功能(springboot),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • win10 下 idea2020安装 JetBrains-agent.jar 包后闪退的问题及解决办法

    win10 下 idea2020安装 JetBrains-agent.jar 包后闪退的问题及解决办法

    这篇文章主要介绍了win10 下 idea2020安装 JetBrains-agent.jar 包后闪退的解决办法,本文给大家带来原因分析及解决方法,需要的朋友可以参考下
    2020-08-08
  • Java实现TCP和UDP协议详解

    Java实现TCP和UDP协议详解

    这篇文章主要介绍了Java实现TCP和UDP协议详解,TCP(传输控制协议)和UDP(用户数据报协议)是两种最常用的传输层协议,它们都用于在网络上传输数据,但是它们之间有很多不同之处,需要的朋友可以参考下
    2023-07-07
  • JavaEE实现基于SMTP协议的邮件发送功能

    JavaEE实现基于SMTP协议的邮件发送功能

    这篇文章主要为大家详细介绍了JavaEE实现基于SMTP协议的邮件发送功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • Java工程的Resources目录从基础到高级应用深入探索

    Java工程的Resources目录从基础到高级应用深入探索

    这篇文章主要介绍了Java工程中的resources目录,从基础概念到高级应用,涵盖了如何创建、使用以及资源文件的加载方法,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-01-01
  • java关于Date日期类型的大小比较

    java关于Date日期类型的大小比较

    这篇文章主要介绍了java关于Date日期类型的大小比较,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • PowerJob UseCacheLock工作流程源码剖析

    PowerJob UseCacheLock工作流程源码剖析

    这篇文章主要为大家介绍了PowerJob UseCacheLock工作流程源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01

最新评论