4.java并发编程艺术-java并发编程基础

  java从诞生开始就明智的选择了内置对多线程的支持,这使得java语言相比同一时期的其他语言具有明显的优势。线程作为操作系统调度的最小单元,多个线程能够同时执行,这将显著提升程序的性能,在多核环境中表现的更加明显。但是,过多的创建线程和对线程的不当管理也容易造成问题。本章将着重介绍java并发编程的基础知识,从启动一个线程到线程间不同的通信方式,最后通过简单的线程池示例以及应用(简单的Web服务器)来串联本章所介绍的内容。

1.线程简介

  1.1 什么是线程

    现代操作系统中在运行一个程序时,会为其创建一个进程。例如,启动一个java程序,操作系统就会创建一个java进程。现在操作系统调度的最小单元就是线程,也叫轻量级进程(Light Weight Process),在一个进程中可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉到这些线程在同时进行。

    一个java程序从main()方法开始执行,然后按照既定的代码逻辑执行,看似没有其他线程参与,但实际上java程序天生就是多线程程序,因为执行main()方法的是一个名称为main的线程,下面使用JMX来查看一个普通的java程序包含哪些线程

public static void main(String[] args) {
        //使用java线程管理MXbean
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        //不需要获取同步的monitor和synchronizer信息,进获取线程和线程堆栈信息
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println("["+threadInfo.getThreadId()+"]"+threadInfo.getThreadName());
        }

    }
//    [7]JDWP Command Reader
//    [6]JDWP Event Helper Thread
//    [5]JDWP Transport Listener: dt_socket
//    [4]Signal Dispatcher    分发处理发送给jvm信号的线程
//    [3]Finalizer            调用对象finalize方法的线程
//    [2]Reference Handler    清除reference 的线程
//     [1]main                    main线程,用户程序入口

    可以看到,一个java程序的运行不仅仅是面()方法的运行,而是main线程和多个其他线程的同时执行。

  1.2 为什么要使用多线程

    执行一个简单的“Hello word!”,却启动了那么多“无关”线程,是不是把简单的问题复杂化了?当然不是,因为真确的使用多线程,总能够给开发人员带来显著的好处,而使用多线程的原因主要有以下几点:

      1.更多的处理器核心

        随着处理器上的核心数量越来越多,以及超线程技术的广泛运用,现在大多数计算机都比以往更加擅长并行计算,而处理器性能的提升方式,也从更高的主频向更多的核心发展。如何利用好处理器上的核心也成了现在的主要问题

        线程是大多数操作系统调度的基本单元,一个程序作为一个进程来运行,程序运行过程中能够创建多个线程,而一个线程在一个时刻只能运行在一个处理器核心上。试想一下,一个单线程程序在运行是只能使用一个处理器核心,那么再多的处理器核心加入也无法显著提升该程序的执行效率。相反,如果改程序使用多线程技术,将计算逻辑分配到多个处理器核心上,就会显著减少程序的处理时间,并且随着更多处理器核心的加入而变得更有效率。

      2.更快的响应时间

        有事我们会编写一些较为复杂的代码(这的复杂代码不是说复杂的算法,而是复杂的业务逻辑)。例如,一笔订单的创建,他包括插入订单数据、生成订单快照、发送邮件通知买家和记录货品销售数量等。用户从单击“订购”按钮开始,就要等待这些操作全部完成才能看到定购成功的结果。但是这么多业务操作,如何能够让其跟快的完成呢?

        在上面的场景中,可以使用多线程技术,即将数据一致性不强的操作派发个其他线程处理(也可以使用消息队列),如生成订单快照、发送邮件等这样做的好处就是想用用户请求的线程能够尽可能的处理完成,缩短了响应时间,提升了用户体验。

      3.更好的编程模型

        java为多线程模型提供了良好、考究并且一致的编程模型,是开发人员能够更加专注于问题的解决,即为所遇到的问题建立合适的模型,而不是绞尽脑汁的考虑如何将其多线程化。一旦开发人员建立好模型,稍做修改总是能够方便的映射到java提供的多线程编程模型上。

  1.3 线程优先级

  1.4 线程的状态

  1.5 Daemon线程

2.启动和终止线程

  2.1 构造线程

  2.2 启动线程

  2.3 理解中断

  2.4 过期的suspend()、resume()、stop()

  2.5 安全的终止线程

3.线程间通信

  3.1 volatile和synchronized关键字

  3.2 等待/通知机制

  3.3 等待/通知经典案例

  3.4 管道输入/输出流

  3.5 Thread.jion()

  3.6 ThreadLocal的使用

4.线程应用实例

  4.1 等待超时模式

  4.2 一个简单的数据库连接池示例

  4.3 线程技术及其示例

  4.4 一个基于线程池技术的简单web服务器

5.本章小结

原文地址:https://www.cnblogs.com/panda777/p/11355589.html

时间: 2024-10-24 12:52:32

4.java并发编程艺术-java并发编程基础的相关文章

3.java并发编程艺术-java内存模型

3.1 java内存模型的基础 3.1.1并发编程模型的两个关键问题 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体).通信是指两个线程 之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种:共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态进行隐式通信.在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来进行显式进行通信. 同步是指程序中用于控制不同线程

前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(上)

第1章.基础篇(上) DOM (Document Object Model) - 文档对象模型 以对象的方式来表示对应的html,它有一系列的规范 i.e. 在浏览器中,DOM是通过JS实现的. DOM: DOM Core:核心结构.API的定义 DOM HTML: 定义HTML如何转化成对象(HTML对应的对象)-- 操作节点 DOM Style:样式转换成对象 -- 操作样式 DOM Event:事件对象的模型 -- 响应用户的操作 文档树 HTML -> DOM树 节点遍历 node.pa

JAVA并发编程艺术 一(并发编程的挑战)

从今天起开始java并发编程艺术的学习,每一章学习完以后再这里记录下内容的重点,做个笔记,加深印象. 并发编程的目的是为了让程序运行的更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行.在进行并发是,如果希望通过多现场执行任务让程序运行得更快,会面临非常多的挑战,比如上下文切换的问题,死锁的问题,以及受限于硬件和软件的资源限制问题,本章会介绍几种并发编程的挑战以及解决方案 1.上下问切换 即使是单核处理器也支持多线程执行代码,cpu通过给每个线程分配cpu时间片来实现这个机制.时间片是

Java 编程之美:并发极速赛车平台出租编程高级篇

借用 Java 并发极速赛车平台出租haozbbs.comQ1446595067 编程实践中的话:编写正确的程序并不容易,而编写正常的并发程序就更难了. 相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的. 并发编程相比 Java 中其他知识点学习起来门槛相对较高,学习起来比较费劲,从而导致很多人望而却步: 而无论是职场面试和高并发高流量的系统的实现却都还离不开并发编程,从而导致能够真正掌握并发编程的人才成为市场比较迫

长文慎入-探索Java并发编程与高并发解决方案

所有示例代码,请见/下载于https://github.com/Wasabi1234/concurrency #1 基本概念##1.1 并发同时拥有两个或者多个线程,如果程序在单核处理器上运行多个线程将交替地换入或者换出内存,这些线程是同时"存在"的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,此时,程序中的每个线程都将分配到一个处理器核上,因此可以同时运行.##1.2 高并发( High Concurrency) 互联网分布式系统架构设计中必须考虑的因素之一,通常是指

Java编程思想之并发

1. 并发的多面性 更快的执行 改进代码设计 2. 基本的线程机制 线程的创建 ``` /* What will be run. */ private Runnable target; @Override public void run() { if (target != null) { target.run(); } } ``` (1) 实现Runnable接口:new Thread(Runnable).start(); 将任务与线程分离,符号面向对象思想,适合多个线程处理统一资源的情况. 可

Java并发编程:Java中的锁和线程同步机制

锁的基础知识 锁的类型 锁从宏观上分类,只分为两种:悲观锁与乐观锁. 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重复读-比较-写的操作.Java中的乐观锁基本都是通过CAS操作实现的,CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败. 悲观

Java并发编程(四):并发容器(转)

解决并发情况下的容器线程安全问题的.给多线程环境准备一个线程安全的容器对象. 线程安全的容器对象: Vector, Hashtable.线程安全容器对象,都是使用 synchronized 方法实现的. concurrent 包中的同步容器,大多数是使用系统底层技术实现的线程安全.类似 native. Java8 中使用 CAS. 1.Map/Set 1.1 ConcurrentHashMap/ConcurrentHashSet 底层哈希实现的同步 Map(Set).效率高,线程安全.使用系统底

并发编程艺术-锁类型以及底层原理

Java并发编程艺术-并发机制的底层原理实现 1.Volatile 定义: Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量. volatile借助Java内存模型保证所有线程能够看到最新的值.(内存可见性) 实现原理: 将带有volatile变量操作的Java代码转换成汇编代码后,可以看到多了个lock前缀指令(X86平台CPU指令).这个lock指令是关键,在多核处理器下实现两个重要操作: 1.将当前处理器缓存行的数据写回到系