首页 > 编程语言 >Java多线程、线程池介绍及多线程间的协同

Java多线程、线程池介绍及多线程间的协同

时间:2024-12-23 19:29:49浏览次数:9  
标签:Java Thread start 线程 new 多线程 public

Java多线程是Java编程中的一个核心概念,它允许程序同时执行多个任务,从而提高程序的执行效率和响应速度。下面我将从线程的创建、线程的状态管理、线程的协作、线程池的使用、同步机制的实现以及并发控制的方法等几个方面来详细介绍Java多线程。

一、线程的创建

在Java中,创建线程主要有三种方式:

继承Thread类‌:
通过自定义一个类继承Thread类,并重写其run方法来实现线程的创建。在run方法中编写线程需要执行的代码。然后创建该类的实例,并调用其start方法来启动线程。

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
    }
}

实现Runnable接口‌:
通过实现Runnable接口,并重写其run方法来实现线程的创建。这种方式的好处是避免了Java单继承的局限性。然后创建Runnable接口的实现类实例,将其作为参数传递给Thread类的构造函数来创建线程对象,并调用start方法启动线程。

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的代码
    }
}

public class Main {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

通过Callable和FutureTask创建线程‌:这种方式创建的线程可以返回值。首先需要创建Callable接口的实现类,并实现其call方法。然后创建Callable实现类的实例,并使用FutureTask类进行包装。最后,将FutureTask对象作为Thread对象的参数来启动新线程,并调用FutureTask对象的get方法获取子线程执行结束后的返回值。

二、线程的状态管理

线程在其生命周期中会经历不同的状态,包括新建(NEW)、可运行(RUNNABLE)、运行(RUNNING)、阻塞(BLOCKED)、等待(WAITING)、计时等待(TIMED_WAITING)和终止(TERMINATED)。

  • 新建状态‌:新创建了一个线程对象,但还没有调用start方法。
  • 可运行状态‌:线程对象创建后,其他线程调用了该对象的start方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权。
  • 运行状态‌:可运行状态的线程获得了CPU时间片,执行程序代码。
  • 阻塞状态‌:线程因为某种原因(如等待某个条件成立)而暂停执行,此时线程不会释放锁。
  • 等待状态‌:线程进入等待状态,等待其他线程的通知(如调用Object类的wait方法)。
  • 计时等待状态‌:线程在等待的同时设置了一个超时时间(如调用Thread类的sleep方法)。
  • 终止状态‌:线程执行完毕或异常退出。

三、线程池的使用

线程池是一种用于管理线程的机制,它可以方便地管理线程,减少内存的消耗,并复用线程。Java中的线程池主要由java.util.concurrent包提供。

  • 创建线程池‌:可以使用Executors类提供的静态方法来创建线程池,如newFixedThreadPool、newCachedThreadPool等。
  • 提交任务‌:使用线程池的submit方法提交任务,任务可以是Runnable接口的实现类或Callable接口的实现类。
  • 关闭线程池‌:使用线程池的shutdown方法关闭线程池,不再接受新任务,但会继续执行已提交的任务。shutdownNow方法则会尝试立即关闭线程池,并尝试停止正在执行的任务。

四、线程的协同

Java线程协同是指多个线程在执行过程中相互协作,共同完成某个任务。这通常涉及到线程之间的通信和同步。

1、基本概念
  1. 线程间的通信‌:

    • 线程间通过共享内存、阻塞队列、信号量等方式进行通信。
    • 线程可以调用某个对象的wait()方法,使自己进入等待状态,同时释放该对象上的锁。另一个线程可以调用相同对象的notify()或notifyAll()方法,唤醒一个或多个处于等待状态的线程。
  2. 线程间的同步

 ‌            synchronized关键字‌:可以用于方法或代码块,实现线程之间的互斥访问。

‌             volatile关键字‌:用于修饰变量,确保变量的可见性,但不能保证原子性。

 ‌            Lock接口‌:提供了更灵活的锁机制,如可重入锁(ReentrantLock)、读写锁(ReadWriteLock)等。

2、并发控制的方法

在Java多线程编程中,并发控制是非常重要的。Java提供了多种并发控制的方法,如信号量(Semaphore)、屏障(CyclicBarrier)、交换器(Exchanger)和条件变量(Condition)等。

  • 信号量‌:用于控制对共享资源的访问数量。
  • 屏障‌:用于让一组线程互相等待,直到所有线程都到达一个共同屏障点时再继续执行。
  • 交换器‌:用于在两个线程之间交换数据。
  • 条件变量‌:与Lock接口配合使用,用于实现线程之间的等待/通知机制。
3、线程协同的实现
  1. 共享内存‌:

    • 多个线程可以访问共享变量或数据结构,通过加锁和解锁来确保数据的一致性。
  2. 等待/通知机制‌:

    • 使用Object类的wait()和notify()/notifyAll()方法实现线程间的协作。
    • 示例代码:
      public class WaitNotifyExample {
          private static final Object lock = new Object();
          private static boolean flag = true;
      
          static class WaitThread implements Runnable {
              @Override
              public void run() {
                  synchronized (lock) {
                      while (flag) {
                          try {
                              lock.wait();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                      System.out.println("WaitThread is running");
                  }
              }
          }
      
          static class NotifyThread implements Runnable {
              @Override
              public void run() {
                  synchronized (lock) {
                      flag = false;
                      lock.notify();
                  }
              }
          }
      
          public static void main(String[] args) {
              Thread waitThread = new Thread(new WaitThread());
              Thread notifyThread = new Thread(new NotifyThread());
              waitThread.start();
              notifyThread.start();
          }
      }
      

  3. 阻塞队列‌:

    • 使用BlockingQueue接口实现线程安全的队列,支持在队尾插入元素和从队首移除元素。
    • 常用于生产者-消费者模式,实现线程间的协作。
  4. 信号量(Semaphore)‌:

    • 用于控制对共享资源的访问,通过acquire()和release()方法实现线程间的同步和协作。
  5. 倒计时门闩(CountDownLatch)‌:

    • 允许一个或多个线程等待其他线程完成操作,当计数器的值为0时,所有等待的线程将被释放。
    • 示例代码:
      import java.util.concurrent.CountDownLatch;
      
      public class CountDownLatchExample {
          public static void main(String[] args) throws InterruptedException {
              CountDownLatch latch = new CountDownLatch(2);
      
              new Thread(() -> {
                  try {
                      System.out.println("Thread A is running");
                      Thread.sleep(1000);
                      latch.countDown();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }).start();
      
              new Thread(() -> {
                  try {
                      System.out.println("Thread B is running");
                      Thread.sleep(1000);
                      latch.countDown();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }).start();
      
              latch.await();
              System.out.println("All tasks are done");
          }
      }
      

  6. 循环栅栏(CyclicBarrier)‌:

    • 允许一组线程互相等待,直到所有线程都到达某个屏障点。
    • 可以重复使用,支持线程间的协作。

标签:Java,Thread,start,线程,new,多线程,public
From: https://blog.csdn.net/jackiendsc/article/details/144657133

相关文章

  • Java的垃圾回收机制介绍、工作原理、算法及分析调优
    Java的垃圾回收(GarbageCollection,GC)是Java虚拟机(JVM)提供的一种自动内存管理机制,用于自动回收不再使用的内存空间,以避免内存泄露和内存溢出等问题。下面主要介绍Java垃圾回收的基本概念、工作原理、算法等。一、JVM内存结构在了解垃圾回收之前,我们需要先了解JVM的内存结构。J......
  • JAVA基础教程-(二)JAVA面向对象编程
    教程目录JAVA基础教程JAVA面向对象编程(二)一、类的成员1.1、属性1.2、方法1.2.1、方法的重载(overload)1.2.2、可变个数形参1.2.3、方法参数的值传递的机制1.3、构造器(构造方法)1.4、总结:属性赋值过程二、面向对象特征:封装和隐藏JAVA基础......
  • javaweb汽车维修保养试驾服务管理系统
    目录项目介绍具体实现截图开发核心技术:开发过程思路核心代码部分展示实验方案:详细视频演示源码获取方式项目介绍本文以java为开发技术,实现了一个期汽车维修保养试驾服务管理系统。服务管理系统的主要使用者分为管理员;个人中心、用户管理、汽车信息管理、试驾预约管......
  • 【java毕设 python毕设 大数据毕设】基于springboot的西山区家政服务网站设计与开发
    ✍✍计算机毕设编程指导师**⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java、Python、小程序、大数据实战项目集⚡⚡文末获取......
  • 【java毕设 python毕设 大数据毕设】基于springboot的物业管理系统的设计与实现 【附
    ✍✍计算机毕设编程指导师**⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java、Python、小程序、大数据实战项目集⚡⚡文末获取......
  • Java项目实战之基于 Spring Boot、MyBatis 和 Vue.js 的智能停车场系统设计与技术选型
    1.系统概述本智能停车场系统旨在为停车场提供高效、便捷的管理解决方案,涵盖车辆进出管理、车位预订、停车费用计算、用户信息管理等功能,同时提供管理员操作界面和用户移动端应用,提升停车场运营效率和用户体验。1.1目标实现停车场自动化管理,提高车位利用率,减少人工成本,为用户提......
  • 继承的介绍、使用-java se进阶 day01
    1.继承的介绍2.继承的使用为什么要使用继承?假如以后要写一个项目,其中程序员一个类,项目经理一个类,Hr一个类,但是这些类的成员都一样如图我们会发现这些成员都是重复的,三个类都写重复的成员十分繁琐,所以我们使用继承,假如有一个类-员工,里面都有这些对象,然后让Coder、Manager、Hr......
  • 最新版的IDEA运行java时怎么看运行过程此操作为(IDEA Debug)
    想必每个学习java的帅哥美女们在运行循环代码的时候,直接看到结果是感觉不真实的,小编今天在学习数组时研究了一个小时都怪我没有好好牢记Random的使用导致了代码的疑问性为此IDEA中有个好用的操作可以查看运行时的步骤是怎样一步一步跑的,废话不多说看下图如图所示为运行步骤......
  • static修饰成员方法、static修饰成员的特点总结、浅聊主方法-java se进阶 day01
    1.工具类的介绍工具类不是用于描述事物的类,而是帮我们完成事情的类(打工)如图当我们编写完这个类后,我们会发现一件事,这个类自己本身并没有意义,这个类完全是给用户进行调用方法的既然是专门给用户调方法,那我们就应该写的更简便点,创建对象,再拿着对象名调用过于麻烦,因此我们在这......
  • 基于Java SpringBoot的音乐网站与分享平台
    @目录摘要1.研究背景2.研究内容3.系统功能3.1前台首页功能模块3.2在线听歌功能模块3.3后台登录功能模块3.4在线听歌管理模块4.部分功能代码实现5.源码分享(免费获取)需要源码联系我即可(免费获取)~✌......