首页 > 编程语言 >Java核心知识体系10-线程管理

Java核心知识体系10-线程管理

时间:2024-11-15 09:20:58浏览次数:1  
标签:10 Java Thread start 线程 new public

Java系列

Java核心知识体系1:泛型机制详解
Java核心知识体系2:注解机制详解
Java核心知识体系3:异常机制详解
Java核心知识体系4:AOP原理和切面应用
Java核心知识体系5:反射机制详解
Java核心知识体系6:集合框架详解
Java核心知识体系7:线程不安全分析
Java核心知识体系8:Java如何保证线程安全性
Java核心知识体系9-并发与多线程:线程基础

在Java程序开发中,线程管理是一个至关重要的方面。它涉及到如何有效地创建、调度、同步和销毁线程,以确保程序的性能、响应性和稳定性。以下是对Java线程管理的详细探讨。

1 线程的基本概念

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。每个线程都有一个独立的执行路径,但共享进程的资源,如内存和文件句柄。在Java中,线程可以通过继承Thread类或实现Runnable接口来创建。

此外,Java 5开始,引入了java.util.concurrent包,提供了更多的并发工具,如Callable接口与Future接口,它们主要用于任务执行。

2 线程的创建与启动

2.1 继承Thread类

  • 创建一个类继承自Thread类。
  • 重写run()方法,该方法包含了线程要执行的任务。
  • 创建该类的对象,并调用start()方法启动线程。
class MyThread extends Thread {
    public void run() {
        System.out.println("线程运行中");
    }
}

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start(); // 调用start()方法来启动线程
    }
}

2.2 实现Runnable接口

  • 创建一个类实现Runnable接口。
  • 实现run()方法,该方法同样包含了线程要执行的任务。
  • 将该类的对象作为参数传递给Thread类的构造函数,创建Thread对象。
  • 调用Thread对象的start()方法启动线程。
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("线程运行中");
    }
}

public class RunnableDemo {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());
        t.start(); // 调用start()方法来启动线程
    }
}

3 线程的同步与通信

由于多个线程可能会同时访问共享资源,因此需要使用同步机制来确保数据的正确性和一致性。Java提供了多种同步机制,如synchronized关键字、wait()notify()方法、以及ReentrantLock等。

3.1 synchronized关键字

  1. 可以用于方法或代码块上,以确保同一时刻只有一个线程能够执行该方法或代码块。
  2. 当一个线程持有某个对象的锁时,其他线程将无法访问该对象的同步方法或代码块,直到锁被释放。
public class SynchronizedExample {
    private int count = 0;

    // 同步方法
    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedExample example = new SynchronizedExample();

        // 创建多个线程来测试同步
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        t1.start();
        t2.start();

        // 等待线程执行完毕
        t1.join();
        t2.join();

        // 输出最终结果
        System.out.println("Final count: " + example.getCount()); // 最终输出2000
    }
}

3.2 wait()和notify()方法

这两个方法用于在线程之间进行通信。

  1. wait()方法使当前线程等待,直到其他线程调用notify()notifyAll()方法唤醒它。
  2. notify()方法唤醒一个等待该对象的线程(如果有多个线程在等待,则选择其中一个),而notifyAll()方法唤醒所有等待该对象的线程。

image

# 先写后读
public class WaitNotifyExample {
    private final Object lock = new Object();
    private boolean ready = false;

    public void writer() throws InterruptedException {
        synchronized (lock) {
            // 模拟写操作
            Thread.sleep(1000); // 假设写操作需要1秒
            System.out.println("Data is ready");
            ready = true;
            lock.notify(); // 唤醒等待的线程
        }
    }

    public void reader() throws InterruptedException {
        synchronized (lock) {
            while (!ready) {
                lock.wait(); // 等待数据准备好
            }
            // 读取数据
            System.out.println("Data has been read");
        }
    }

    public static void main(String[] args) {
        WaitNotifyExample example = new WaitNotifyExample();

        Thread writerThread = new Thread(example::writer);
        Thread readerThread = new Thread(example::reader);

        writerThread.start();
        readerThread.start();
    }
}

3.3 ReentrantLock

  1. 提供了比synchronized更灵活的锁机制。
  2. 可以显式地加锁和解锁,还支持公平锁和非公平锁等特性。

四、线程的生命周期与状态

Java线程在其生命周期中会经历多种状态,包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed Waiting)和终止(Terminated)。

  • 新建(New):线程被创建但尚未启动。
  • 就绪(Runnable):线程已启动且正在等待CPU分配时间片。
  • 运行(Running):线程正在执行其任务。
  • 阻塞(Blocked):线程因等待某个条件而暂时停止执行。
  • 等待(Waiting):线程因调用wait()方法而等待其他线程唤醒。
  • 超时等待(Timed Waiting):线程在等待某个条件的同时还设置了一个超时时间。
  • 终止(Terminated):线程已完成任务并退出。

image

5 线程池

为了更有效地管理线程,Java提供了线程池机制。线程池是一种用于管理和复用线程的框架,它允许开发者以较小的开销来创建和管理大量的线程。Java中的ExecutorService接口及其实现类(如ThreadPoolExecutor)提供了强大的线程池功能。
Java中提供了几种常见的线程池类型,包括:

  1. FixedThreadPool(固定大小线程池):包含固定数量的线程,适用于需要限制并发线程数量的场景。
  2. CachedThreadPool(缓存线程池):不固定线程数量,可以根据需要自动创建新线程,适用于短期异步任务。
  3. SingleThreadPool(单线程池):只包含一个工作线程,保证所有任务按顺序执行,适用于需要保持任务顺序执行的场景。
  4. ScheduledThreadPool(定时线程池):可以执行定时任务和周期性任务。
  5. WorkStealingPool(工作窃取线程池):Java 8中引入的一种新类型的线程池,主要用于处理耗时任务,适用于需要大量并行任务、任务之间没有依赖关系的情况。

在后续的章节里面,我们会专门来详细介绍下线程池的使用

6 最佳实践

  • 避免创建过多的线程:过多的线程会导致上下文切换频繁,从而降低系统性能。
  • 合理设置线程优先级:根据任务的紧急程度和重要性来设置线程的优先级。
  • 使用线程安全的集合:在多线程环境下使用线程安全的集合来避免数据不一致的问题。
  • 避免死锁:在设计多线程程序时要特别注意避免死锁的发生。

综上所述,Java线程管理是一个复杂而重要的领域。通过合理地创建、调度、同步和销毁线程,可以显著提高程序的性能、响应性和稳定性。同时,开发者还需要遵循一些最佳实践来避免常见的问题和陷阱。

标签:10,Java,Thread,start,线程,new,public
From: https://www.cnblogs.com/wzh2010/p/15886703.html

相关文章

  • java 反序列化 cc5复现
    复现环境:common-collections版本<=3.2.1,java版本随意.cc5则是cc6的一个变形,换了一个出口.直接从有变化的位置开看.TiedMapEntrypublicclassTiedMapEntryimplementsMap.Entry,KeyValue,Serializable{privatestaticfinallongserialVersionUID=-84538693613......
  • Java面试要点20 - Java接口的演进
    本文目录一、引言二、传统接口特性三、Java8中的默认方法四、静态方法的引入五、Java9私有方法六、接口的多重实现七、总结一、引言Java接口是一种抽象类型,是抽象方法的集合,用于规范类的行为。从Java8开始,接口的功能不断增强,引入了默认方法和静态方法,到Java9......
  • 【原创】java+ssm+mysql物流信息网系统设计与实现
    个人主页:程序猿小小杨个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎博客内容:Java项目实战、项目演示、技术分享文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交给天意。前言:随着全球经济一体化的不断推进,物流业作为支撑企业运营的重要环节,其管理和......
  • 【原创】java+ssm+mysql商品库存管理系统(进销存)设计与实现
    个人主页:程序猿小小杨个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎博客内容:Java项目实战、项目演示、技术分享文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交给天意。前言:随着市场竞争的日益激烈,企业面临着巨大的竞争压力。为了在市场中立于不败......
  • 光伏场地建设规划 E100
    题目描述祖国西北部有一片大片荒地,其中零星的分布着一些湖泊,保护区,矿区;整体上常年光照良好,但是也有一些地区光照不太好。某电力公司希望在这里建设多个光伏电站,生产清洁能源,对每平方公里的土地进行了发电评估,其中不能建设的区域发电量为0kw,可以发电的区域根据光照,地形等......
  • 【JavaEE初阶 — 多线程】生产消费模型 & 阻塞队列
         1.阻塞队列     (1)阻塞队列   1.概念   阻塞队列是一种特殊的队列,也遵守"先进先出"的原则;阻塞队列能是一种线程安全的数据结构,主要用来阻塞队列的插入和获取操作:当队列满了的时候,插入操作会被阻塞,直到队列有空位。当队列为空的时......
  • 【洛谷】P1047 [NOIP2005 普及组] 校门外的树
    题目描述某校大门外长度为 l 的马路上有一排树,每两棵相邻的树之间的间隔都是 1 米。我们可以把马路看成一个数轴,马路的一端在数轴 00 的位置,另一端在 l 的位置;数轴上的每个整数点即 0,1,2,…,l都种有一棵树。由于马路上有一些区域要用来建地铁。这些区域用它们在数......
  • [RoarCTF 2019]Easy Java 1
    [RoarCTF2019]EasyJava1打开实例发现登录框,尝试万能密码admin'or1=1#后无果注意到登录框下有个help,点击发现文件读取显示文件notfound,文件未找到,怀疑是请求方法问题,尝试POST请求发现能成功下载,确定这道题为任意文件下载打开help.docx,显示看来文件不在这里,根据题目......
  • 【学习日记】notebook添加JAVA支持
    作者是个大学生这个专栏主要收集课时常用的软件以及女朋友上课用的软件的教程新开了gitcode用于上传安装包 环境说明windows11java23.0.1ijava1.1.2Anaconda-2024.02需提前配置好java环境本篇仅对添加支持进行说明ijava的GitCode链接NotebookAddsSupportForJava......
  • Java面试之有三个线程T1,T2,T3,如何保证顺序执行?
    前言本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!有三个线程T1,T2,T3,如何保证顺序执行?似乎有点模糊了,那就大概看一下面试题吧。好记性不如烂键盘***12万字的java面试题整理***有三个线程T1,T2,T3,如何保证顺序执行?在多线程中有多种方法让线程按特定顺序执行,......