博客
关于我
多线程编程基础
阅读量:479 次
发布时间:2019-03-06

本文共 5552 字,大约阅读时间需要 18 分钟。

多线程编程基础

进程与线程的基础概念

进程

进程是程序运行的核心单元,是系统资源分配和调度的基本单位。每个进程都有独立的代码和数据空间,进程间切换会产生一定的开销。

  • 进程的特点

    进程是一个程序的一次执行实例,通常包含代码段、数据段和堆栈段。它是系统调度的基本单位。

  • 多进程环境

    多进程允许多个任务同时运行,通过系统调度将CPU资源分配给各个进程。

线程

线程是进程中的一个独立执行单元,是CPU调度的基本单位。与进程相比,线程具有更小的粒度,线程切换开销更低。

  • 线程的定义

    线程是进程中的一个执行实体,负责执行包含在进程地址空间中的代码。每个线程有自己的运行栈和程序计数器,但共享进程的其他资源。

  • 线程的作用

    线程允许多个任务在进程内部同时执行,提升系统效率。

进程的三大特征

  • 独立性

    进程可以独立地分配和管理资源。

  • 动态性

    进程的状态可以随着运行环境发生改变。

  • 并发性

    多个进程可以同时运行,通过系统调度实现并发执行。

  • 启动进程的方法

    通过不同的方式可以启动新的进程,以下是常用的两种方法:

    方法一:使用ProcessBuilder

    ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "ipconfig/all");Process p = pb.start();// 读取进程输出BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));while ((temp = br.readLine()) != null) {    System.out.println(temp);}

    方法二:使用Runtime.exec

    String cmd = "cmd " + "/c " + "ipconfig/all";Process process = Runtime.getRuntime().exec(cmd);// 读取进程输出BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));while ((temp = br.readLine()) != null) {    System.out.println(temp);}

    动态生成代码并编译执行

    // 删除已存在的文件File f = new File("T1.java");if (f.exists()) {    f.delete();}// 生成代码文件PrintWriter pw = new PrintWriter(new FileWriter("T1.java"));pw.println("public class T1 {");pw.println("public static void main(String[] args) throws Exception {");pw.println("System.out.println(\"Hello Java!\");");pw.println("}}");pw.close();// 编译代码Process process = Runtime.getRuntime().exec("cmd /c javac T1.java");// 执行已编译的类process = Runtime.getRuntime().exec("cmd /c java T1");

    线程的实现方法

    线程可以通过不同的方式实现,以下是常用的四种方法:

    1. 继承Thread类

    public class LeftThread extends Thread {    public void run() {        for (int i = 0; i < 50; i++) {            System.out.println("左手一个慢动作...");            try {                Thread.sleep(500);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}// 启动线程Thread t1 = new LeftThread();t1.start();

    2. 实现Runnable接口

    public class RightRunnable implements Runnable {    public void run() {        for (int i = 0; i < 50; i++) {            System.out.println(Thread.currentThread().getName() + ":右手慢动作重播!");        }    }}// 启动线程Thread t2 = new Thread(new RightRunnable());t2.start();

    3. 使用Callable和Future

    public class MyCallable implements Callable
    { private int begin; private int end; public MyCallable(int begin, int end) { this.begin = begin; this.end = end; } public Integer call() throws Exception { System.out.println(Thread.currentThread() + "---" + begin + ".." + end); int res = 0; for (int i = begin; i <= end; i++) { res += i; } return res; }}// 使用FutureTask创建线程FutureTask
    ft = new FutureTask
    (new MyCallable(1, 100));Thread t = new Thread(ft);t.start();int sum = ft.get();

    4. 使用线程池

    public class T1 {    public static void main(String[] args) throws Exception {        ExecutorService es = Executors.newFixedThreadPool(3);        Future[] fs = new Future[10];        for (int i = 0; i < 10; i++) {            Callable
    caller = new MyCallable(i * 1000 + 1, (i + 1) * 1000); fs[i] = es.submit(caller); } int res = 0; for (int i = 0; i < fs.length; i++) { Object obj = fs[i].get(); if (obj instanceof Integer) { res += (Integer) obj; } } es.shutdown(); System.out.println("Main:" + res); }}

    线程池的实现

    线程池通过管理线程的生命周期,优化了线程资源的使用。常用的线程池实现包括:

    固定线程池

    ExecutorService es = Executors.newFixedThreadPool(3);// 创建多个Callable任务,并提交到线程池for (int i = 0; i < 10; i++) {    Callable
    task = () -> { // 实现具体的任务逻辑 try { // 假设任务涉及计算 System.out.println("正在计算:" + i); Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }; Future
    future = es.submit(task); // 等待任务完成 future.get();}es.shutdown();

    可扩展线程池

    ExecutorService es = Executors.newCachedThreadPool();for (int i = 0; i < 100; i++) {    Callable
    task = () -> { System.out.println("新任务提交:" + i); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }; Future
    future = es.submit(task); // 等待任务完成 future.get();}es.shutdown();

    线程间的通信与同步

    线程间的通信和同步至关重要,以下是一些常用的机制:

    同步机制

    • synchronized 关键字

      可以锁定特定方法或代码块,防止多个线程同时访问。

    • Lock 接口

      使用第三方库如LockUtils实现更细粒度的锁。

    通信机制

    • Wait/Notify

      通过等待和通知机制实现线程间的同步。

    • CountDownLatch

      用于等待多个线程的完成。

    • CyclicBarrier

      用于多个线程在完成各自任务后,等待于一个共同的点。

    线程的终止与资源收集

    线程的终止需要谨慎处理,以避免资源泄漏。系统提供了以下机制:

    终止线程

    public class T1 implements Runnable {    private boolean running = true;    public void run() {        try {            while (running) {                System.out.println("线程在运行");                Thread.sleep(100);            }        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        Thread t = new Thread(new T1());        try {            Thread.sleep(2000);            running = false;        } catch (InterruptedException e) {            e.printStackTrace();        }        t.interrupt();        t.join();        System.out.println("线程已终止");    }}

    资源收集

    孤儿进程和僵尸进程是多线程环境中的常见问题,需要妥善处理:

    • 孤儿进程

      当父进程退出而子进程仍在运行时,孤儿进程会被init进程收养。

    • 僵尸进程

      当子进程退出但父进程未释放资源时,僵尸进程会占用系统资源,需及时回收。

    并行与并发的理解

    • 并行

      多个处理器同时执行相同任务,真正意义上的同时执行。

    • 并发

      通过时间片轮转,使得看起来多个任务同时执行,但实际上是交替执行的。

    多线程编程的优点

  • 资源利用更高效

    线程的创建和切换开销较低。

  • 吞吐量更高

    CPU资源得到充分利用,减少空转时间。

  • 扩展性更好

    通过增加处理器核心,系统性能得到显著提升。

  • 总结

    多线程编程是一种强大的编程范式,通过合理利用系统资源,可以显著提升程序的性能和响应速度。在实际应用中,选择合适的线程和同步机制至关重要,以确保程序的健壮性和稳定性。

    转载地址:http://xbbdz.baihongyu.com/

    你可能感兴趣的文章
    mysql5.6 TIME,DATETIME,TIMESTAMP
    查看>>
    mysql5.6.21重置数据库的root密码
    查看>>
    Mysql5.6主从复制-基于binlog
    查看>>
    MySQL5.6忘记root密码(win平台)
    查看>>
    MySQL5.6的Linux安装shell脚本之二进制安装(一)
    查看>>
    MySQL5.6的zip包安装教程
    查看>>
    mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
    查看>>
    Webpack 基本环境搭建
    查看>>
    mysql5.7 安装版 表不能输入汉字解决方案
    查看>>
    MySQL5.7.18主从复制搭建(一主一从)
    查看>>
    MySQL5.7.19-win64安装启动
    查看>>
    mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
    查看>>
    MySQL5.7.37windows解压版的安装使用
    查看>>
    mysql5.7免费下载地址
    查看>>
    mysql5.7命令总结
    查看>>
    mysql5.7安装
    查看>>
    mysql5.7性能调优my.ini
    查看>>
    MySQL5.7新增Performance Schema表
    查看>>
    Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
    查看>>
    Webpack 之 basic chunk graph
    查看>>