博客
关于我
线程之前的共享和协作
阅读量:696 次
发布时间:2019-03-17

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

线程基础概述

进程与线程的基础知识

在操作系统中,进程和线程是资源分配和调度的两种核心概念。进程是操作系统分配资源(如CPU、内存)的基本单位,而线程则是处理CPU调度的最小单位。理解这两者的区别对于编写并发程序至关重要。

  • 进程:相比线程,进程的执行资源需求更大,常被看作一个应用程序的运行环境。通过启动一个进程,可以运行一个独立的程序。例如,打开一个文件资源管理器或浏览器就是启动了一个新的进程。

  • 线程:线程则更小,是CPU调度的基本单位。每个线程共享进程的资源,可以独立执行任务。一个进程中可以运行多个线程,线程之间通过共享堆内存进行通信和同步。线程的数量直接关系到程序的并行执行能力。

CPU核心数与线程数的关系

现代计算机的多核处理器支持多线程并行执行,但线程与CPU核心的关系并非线性直接关系。在单线程程序中,每个核心都可以执行一个线程。但现代处理器支持超线程技术,使得一个核心内核可以同时处理多个逻辑核心线程。

需要注意的是,与内核数量关系不大,线程的调度主要依赖操作系统的轮转机制(RR调度)。

CPU时间片轮转机制

操作系统通过CPU时间片轮转机制进行进程调度,将任务分配给各个核心。每个线程获得一定的CPU时间片后执行,只有在超时后才被替换,释放所占用的CPU。

根据测量结果,1.6GHz的CPU执行一个操作instructions(约 resurgence time)大约需要0.6纳秒。该时间间隔对于线程间切换来说是关键参数。上下文切换需要耗费大量时间,尤其是内核态操作,每次切换需要数以万计的CPU周期。

并行与并发的区别

计算机科学中的并行和并发概念常被互换,但二者有根本差异:

  • 并行:涉及能够同时运行多个任务。例如,多核处理器可以同时处理多个线程,这些线程互不干扰地执行不同的任务。

  • 并发:指单时间内可以处理的任务数量。并发与并行的区别在于时序,任务是交替执行的,而非本部件层面同时运行。

理解这一点至关重要。并行更多是指任务本身的并行执行,而并发更多关注时间维度上的处理数量。

高并发编程的意义与注意事项

高并发编程能显著提升系统性能,解决性能瓶颈,并简化代码结构。常见优势:

  • 资源充分利用:通过并行处理,充分利用CPU、内存等资源,提升性能表现。

  • 提升用户体验:快速响应用户请求,减少等待时间。

  • 代码简化:通过任务异步化和模块化设计,便于系统扩展和维护。

  • 然而,高并发编程也伴随着潜在问题:

  • 线程安全:线程共享资源,可能导致竞态条件和死锁。需通过锁机制和其他同步方式加以防范。

  • 性能开销:频繁的线程调度和上下文切换会增加系统负担,影响性能。

  • 资源限制:每个进程(如Linux)最多支持1000个线程,需谨慎管理资源分配。

  • 推荐使用线程池进行高并发处理,以控制并发深度并优化资源利用率。


    新启线程的方式

    在Java中,可以通过Thread类或Runnable接口来创建线程:

    1. 使用Thread

    Thread类提供了线程创建和管理的底层功能。创建方式:

    new Thread(task);

    适用于需要控制线程生命周期、带有异常处理能力的场景。

    2. 使用Runnable接口

    Runnable更注重任务本身的逻辑实现,适合异步执行:

    new Thread(task).start();

    叶目标是让任务在独立线程中运行。

    两者的区别在于,Thread类提供了解决并发问题的完整控制,而Runnable更注重对业务逻辑的抽象。


    中断机制

    线程中断是协作式多线程编程中的重要机制,为线程提供协调退出方式。

    使用stop()方法的弊端

    stop()方法要求线程主动释放资源,但其调用的线程可能无法释放资源而导致内存泄漏。

    中断的正确处理方式

  • 使用integrated();方法对线程发出中断信号。

  • 由于InterruptedException可能不会导致线程终止,需结合interrupted()方法判断线程的中断状态。

  • 非 daemon 线程(后台线程)在中断后仍需主动终止。需在异常处理中添加interrupt()方法,确保线程终止。

  • class MyThread extends Thread {    @Override    public void run() {        try {            while (!isInterrupted()) {                sleep(1000);  // sleep 不抛出 InterruptedException            }        } catch (InterruptedException e) {            e.printStackTrace();            interrupted(); // 重置中断标志位            start(); // 供其他线程中断信息处理时调用        }    }}

    线程的生命周期管理

    线程从启动到终止经历了以下阶段:

  • 新生线程:创建Thread对象,设置默认优先级,指针方式调度。
  • 停止线程:调用stop()或只设置为不可运行状态(通过start()多次调用会抛异常)。
  • 执行线程:线程进入运行状态,及时获得CPU资源。
  • 被中断:线程停止执行,释放资源。
  • 终止:线程获得死亡状态。
  • 常见方法解释

    • start():启动线程,准备好运行新的线程。
    • run():可在run()方法中实现任务逻辑,本身可以重复调用。
    • join():线程礼让,等待线程执行完成。
    • yield():线程让出CPU,允许其他线程占用资源,但不会释放锁。

    线程管理不当可能导致资源泄漏和性能问题。谨慎使用join()和其他阻塞方法。


    数据共享与保护机制

    Synchronized关键字

    线程安全是并发编程的重要关注点。Synchronized(内置锁)主要用于保护共享资源的可见性和排他性,防止多线程竞骤访问和修改。

    它可以修饰方法或代码块。通过匿名锁机制,可以实现更细粒度的锁控制。

    Volatile关键字

    Volatile目标变量具有可见性和一致性,但不保证原子性。在多线程环境下,一写多读时需要保护读写锁,可以通过Volatile变量配合其他机制(如atomic references)实现可靠的写入和读取。


    ThreadLocal变量

    ThreadLocal允许每个线程获得自己的属性副本,使其线程独立,避免共享资源冲突。常见用途包括抢抓资源和事务处理。正确管理ThreadLocal变量至关重要,以防止内存泄漏和资源竞争。建议及时释放变量,避免存储大量未使用的keyup。


    线程间的协作与通信

    线程间需通过协作完成任务,常用的机制包括等待通知组以及信号代理。生产者-消费者模型是线程协作的典型案例。

    等待/通知机制

    • 等待方:在不满意条件时调用对象的wait()方法。

    • 通知方:修改条件后调用notify()或notifyAll()。

    调用这些方法需联任有对象锁,否则可能导致并发问题。

    Join()方法

    Join()方法可以让线程等待另一个线程运行完毕。这对于线程的正序执行至关重要。


    结语

    本文系统介绍了线程基础、并发编程、高级线程管理和安全性机制等核心内容,提供了实践的代码示例和理论分析。理解线程运作机制与底层原理,是掌握并发编程的基石。

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

    你可能感兴趣的文章
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>
    mysql一个字段为空时使用另一个字段排序
    查看>>
    MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>
    MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
    查看>>
    MySQL不同字符集及排序规则详解:业务场景下的最佳选
    查看>>
    Mysql不同官方版本对比
    查看>>
    MySQL与Informix数据库中的同义表创建:深入解析与比较
    查看>>
    mysql与mem_细说 MySQL 之 MEM_ROOT
    查看>>
    MySQL与Oracle的数据迁移注意事项,另附转换工具链接
    查看>>
    mysql丢失更新问题
    查看>>
    MySQL两千万数据优化&迁移
    查看>>
    MySql中 delimiter 详解
    查看>>
    MYSQL中 find_in_set() 函数用法详解
    查看>>
    MySQL中auto_increment有什么作用?(IT枫斗者)
    查看>>