JAVA之多线程

这篇具有很好参考价值的文章主要介绍了JAVA之多线程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

进程与线程

  1. 进程是指运行中的应用程序,每一个进程都有自己独立的内存空间;
  2. 线程是指进程中的一个执行流程,有时也称为执行情景;
  3. 一个进程可以由多个线程组成,即在一个进程中可以同时运行多个不同的线程,它们分别执行不同的任务;
  4. 当进程内的多个线程同时运行,这种运行方式称为并发运行;

多线程的生命周期

JAVA之多线程,java,多线程

  1. 就绪状态:就绪状态的线程又叫做可运行状态,表示当前线程具有抢夺CPU时间片的权力(CPU时间片就是执行权)。当一个线程抢夺到CPU时间片之后,就开始执行run方法,run方法的开始执行标志着线程进入运行状态。

  2. 运行状态:run方法的开始执行标志着这个线程进入运行状态,当之前占有的CPU时间片用完之后,会重新回到就绪状态继续抢夺CPU时间片,当再次抢到CPU时间之后,会重新进入run方法接着上一次的代码继续往下执行。

  3. 阻塞状态:当一个线程遇到阻塞事件,例如接收用户键盘输入,或者sleep方法等,此时线程会进入阻塞状态,阻塞状态的线程会放弃之前占有的CPU时间片。之前的时间片没了需要再次回到就绪状态抢夺CPU时间片。

  4. 锁池:在这里找共享对象的对象锁线程进入锁池找共享对象的对象锁的时候,会释放之前占有CPU时间片,有可能找到了,有可能没找到,没找到则在锁池中等待,如果找到了会进入就绪状态继续抢夺CPU时间片。(这个进入锁池,可以理解为一种阻塞状态)

多线程的实现方式

  1. 继承java.lang.Thread类 :extends
    Thread类代表线程类,它的最主要的两个方法是:
    run():包含线程运行时所执行的代码。
    start():用于启动线程。
package extendth;
public class Machine extends Thread{
  public void run(){
    for(int a=0;a<50;a++)
      System.out.println(a);
  }
  
  public static void main(String args[]){
    Machine machine=new Machine();
    machine.start();  //启动machine线程
  }	
}
  1. 实现Runnable接口:implements
package runimpl;
public class Machine implements Runnable{
  private int a=0;
  public void run(){
    for(a=0;a<50;a++){
      System.out.println(Thread.currentThread().getName()+":"+a);
      try{
        Thread.sleep(100);
      }catch(InterruptedException e){throw new RuntimeException(e);}
    }
  }
  public static void main(String args[]){
    Machine machine=new Machine();
    Thread t1=new Thread(machine);
    Thread t2=new Thread(machine);
    t1.start();
    t2.start();
  }
}
  1. 线程池实现
    先创建一个线程池工具类,再调用工具类方法实现。
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/*
 * 线程池工具类
 * 使用的话 : 获取线程池: ThreadUtils.getInstance().getExecutor();
 *           执行任务:  ThreadUtils.getInstance().execute(Runnable runnable);
 *           杀死线程:  ThreadUtils.getInstance().remove(Runnable runnable);
 *
 * */
public class ThreadPoolUtil {

    /*
     * volatile 保证变量操作的可见性,也防止指令重排序   应用就是双锁检测的单例模式
     * */
    private static volatile ThreadPoolUtil mInstance;

    /**
     * 核心线程池的数量,同时能够执行的线程数量
     */
    private int corePoolSize;
    /**
     * 最大线程池数量,表示当缓冲队列满的时候能继续容纳的等待任务的数量
     */
    private int maxPoolSize;
    /**
     * 存活时间
     */
    private long keepAliveTime = 1;

    private ThreadPoolExecutor executor;

    public ThreadPoolExecutor getExecutor() {
        return executor;
    }

    private ThreadPoolUtil() {
        //给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)
        corePoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
        maxPoolSize = corePoolSize;
        TimeUnit unit = TimeUnit.HOURS;
        executor = new ThreadPoolExecutor(
                //当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务
                corePoolSize,
                // 然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
                maxPoolSize,
                //表示的是maximumPoolSize当中等待任务的存活时间
                keepAliveTime,
                unit,
                //缓冲队列,用于存放等待任务,Linked的先进先出
                new LinkedBlockingQueue<>(),
                new DefaultThreadFactory(Thread.NORM_PRIORITY, "thread-pool-"),
                new ThreadPoolExecutor.AbortPolicy()
        );
    }

    /**
     * 获取线程池单例
     */
    public static ThreadPoolUtil getInstance() {
        if (mInstance == null) {
            synchronized (ThreadPoolUtil.class) {
                if (mInstance == null) {
                    mInstance = new ThreadPoolUtil();
                }
            }
        }
        return mInstance;
    }

    /**
     * 执行任务
     */
    public void execute(Runnable runnable) {
        if (executor == null) {
            executor = new ThreadPoolExecutor(
                    corePoolSize,
                    maxPoolSize,
                    keepAliveTime,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(),
                    new DefaultThreadFactory(Thread.NORM_PRIORITY, "thread-pool-"),
                    new ThreadPoolExecutor.AbortPolicy());
        }
        if (runnable != null) {
            executor.execute(runnable);
        }
    }

    /**
     * 移除任务
     */
    public void remove(Runnable runnable) {
        if (runnable != null) {
            executor.remove(runnable);
        }
    }

    private static class DefaultThreadFactory implements ThreadFactory {
        //线程池的计数
        private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
        //线程的计数
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final String namePrefix;
        private final int threadPriority;

        DefaultThreadFactory(int threadPriority, String threadNamePrefix) {
            this.threadPriority = threadPriority;
            this.group = Thread.currentThread().getThreadGroup();
            this.namePrefix = threadNamePrefix + POOL_NUMBER.getAndIncrement() + "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            // 返回True该线程就是守护线程,守护线程应该永远不去访问固有资源,如:数据库、文件等。因为它会在任何时候甚至在一个操作的中间发生中断。
            if (thread.isDaemon()) {
                thread.setDaemon(false);
            }
            thread.setPriority(threadPriority);
            return thread;
        }
    }

	//测试
 	public static void main(String[] args) {
        ThreadPoolExecutor newThreadPoolExecutor=getInstance().getExecutor();
        for (int i = 0; i < 100; i++) {
            int n = i;
            newThreadPoolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() +"正在执行任务");
                }
            });
        }
    }
}

使用方法:
获取线程池: ThreadUtils.getInstance().getExecutor();
执行任务: ThreadUtils.getInstance().execute(Runnable runnable);
杀死线程: ThreadUtils.getInstance().remove(Runnable runnable);文章来源地址https://www.toymoban.com/news/detail-725807.html

到了这里,关于JAVA之多线程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaEE之多线程编程:4. 线程安全(重点!!!)

    下面我们来举个例子: 我们大家都知道,在单线程中,以下的代码100%是正确的。 但是,两个线程,并发的进行上述循环,此时逻辑可能就出现问题了。 上述这样的情况就是非常典型的线程安全问题。这种情况就是bug!! 只要实际结果和预期的结果不符合,就一定是bug。 想

    2024年01月25日
    浏览(41)
  • JavaEE之多线程编程:3. 线程的状态(易懂!)

    进程 最核心的状态,一个是就绪状态,一个是阻塞状态(对于线程同样使用)。 以线程为单位进行调度的。 在Java中,又给线程赋予了一些其他的状态。 线程的状态是一个枚举类型 Thread.State 线程的状态一共有6个: NEW:安排了工作, 还未开始行动。(Thread对象已经有了,.

    2024年01月19日
    浏览(50)
  • Rust语言之多线程

    多线程 是一种并发执行的技术,它允许一个程序或进程同时执行多个线程。每个线程都是程序执行的一个独立路径,它们可以并行运行,共享进程的资源(如内存空间),但每个线程有自己的指令指针、堆栈和局部变量。多线程的主要目的是提高程序的执行效率,通过同时执

    2024年02月22日
    浏览(36)
  • Linux之多线程(上)——Linux下的线程概念

    本文介绍了地址空间和二级页表、Linux下的线程、线程的优缺点以及线程与进程的关系等概念。 地址空间是进程能看到的资源窗口 :一个进程可以看到代码区、堆栈区、共享区、内核区等,大部分的资源是在地址空间上看到的。 页表决定进程真正有用资源的情况 :进程认为

    2024年02月09日
    浏览(44)
  • Python笔记二之多线程

    本文首发于公众号:Hunter后端 原文链接:Python笔记二之多线程 这一篇笔记介绍一下在 Python 中使用多线程。 注意 :以下的操作都是在 Python 3.8 版本中试验,不同版本可能有不同之处,需要注意。 本篇笔记目录如下: 概念 多线程的使用示例 daemon run() 线程对象的属性和设置

    2024年02月03日
    浏览(64)
  • Linux入门之多线程|线程的同步|生产消费模型

    文章目录 一、多线程的同步 1.概念 2.条件变量 2.1条件变量概念 2.2条件变量接口 1.条件变量初始化 2.等待条件满足 3.唤醒等待 3.销毁条件变量 2.3条件变量demo 二、生产消费模型 1.生产消费模型 2.基于BlockQueue的生产者消费者模型 3.基于C++用条件变量和互斥锁实现一个生产消费模

    2024年02月09日
    浏览(39)
  • Linux入门之多线程|线程|进程基本概念及库函数

    目录 一、线程 1.线程的概念 补充知识点:页表 2.线程的优点 3.线程的缺点 4.线程异常 5.线程用途 二、线程与进程的区别与联系 三、关于进程线程的问题 0.posix线程库 1.创建线程 关于pthread_create的后两个参数 1.传入指针 2.传入对象 2.线程终止 3.取消线程 4.线程等待(等待线程

    2024年02月10日
    浏览(39)
  • JavaEE之多线程编程:5. 死锁(详解!!!)

    死锁是这样的一种情形:多个同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 【举个例子理解死锁】 张三李四两人去吃饺子,吃饺子需要酱油和醋。 张三抄起了酱油瓶, 李四抄起了醋瓶。 张三:你先把

    2024年01月25日
    浏览(42)
  • JavaEE之多线程编程:2.创建线程及Thread类常见方法(超全!!!)

    Java中创建线程的写法有很多种!!!这里介绍其中5种。 方法1:继承Thread类,重写run 创建一个类,让这个类继承自Thread父类,再重写我们的run方法就可以了。 使用Thread类,不需要import别的包,因为它是再Java.lang下面的。 注意: start() 是创建了一个新的线程,由新的线程来执

    2024年02月04日
    浏览(34)
  • 互联网编程之多线程/线程池TCP服务器端程序设计

    目录 需求 多线程TCP服务器 线程池TCP服务器 测试 日志模块 多线程TCP服务器(30分): 设计编写一个TCP服务器端程序,需使用多线程处理客户端的连接请求。客户端与服务器端之间的通信内容,以及服务器端的处理功能等可自由设计拓展,无特别限制和要求。 线程池TCP服务器

    2024年02月11日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包