`
gaotong1991
  • 浏览: 93030 次
  • 来自: 北京
社区版块
存档分类
最新评论

你必须知道的Java并发编程基础知识

阅读更多

1. 并发

1.1. 什么是并发?

并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力。如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善。现代的PC都有多个CPU或一个CPU中有多个核。是否能合理运用多核的能力将成为一个大规模应用程序的关键。

1.2. 进程 vs. 线程

进程是以独立于其他进程的方式运行的,进程间是互相隔离的。一个进程无法直接访问另一个进程的数据。进程的资源诸如内存和CPU时间片都是由操作系统来分配。

 

线程又被称为轻量级进程。每个线程有它独自的调用栈, 但是在同一进程下的线程又能互相访问它们间的共享数据。每个线程都有它独自的缓存。如果一个线程读取了某些共享数据,那么它将这些数据存放在自己的缓存中以供将来再次读取。

一个JAVA应用程序默认以一个进程的形式运行着。在一个JAVA程序中,你将协同多个不同的线程一起完成并行运算或实现异步行为。

2. 并发的改进与问题

2.1. 并发性能的上限

之所以并发号称能较快的完成某些任务是因为这些任务能被分组成多个子任务,并且这些子任务能被并行的执行。所以一个任务的实际运行效率将受限于该任务中能并行执行的部分。

一个程序理论上可达到的最高并发性能可通过以下一个被称为Amdahl 定律来计算出:

设F为一个程序中不能被并行执行的百分比,N是处理器的数量,那么理论上该程序能获得的最高并发性能将可能是1/ (F+ ((1-F)/n)).

2.2. 并发问题

线程有独自的调用栈,但是又能互相访问共享的数据。所以这里你会遇到两个问题,可见性和访问。

可见性问题发生于如果线程A先读取了某些共享数据,之后线程B对这些数据进行了修改,那么线程A可能看不到线程B对这数据的改动。

访问问题发生于于 多个线程同时访问修改同一个共享数据。

可见性及访问问题将导致

  • 活跃性失败:由于并发访问数据导致程序无任何反应。 譬如,死锁。
  • 安全性失败:程序创建了错误的数据。
  • 3. JAVA中的并发

    3.1. 进程与线程

    一个JAVA程序默认以一个线程运行在自己的进程中。JAVA语言通过Thread相关代码来支持线程。JAVA程序可通过Thread这个类来创建线程。从JAVA1.5起,在java.util.concurrent中提供了改进的并发库。

    3.2. 锁和线程同步

    JAVA提供了“锁” 机制来保护代码片段免于被多个线程在同一时刻运行。最简单的锁住一个方法或一个类就是在该方法或类前添加synchronized关键字

    在Java中synchronized关键字保证了:

    • 在同一时刻,只有单个线程能访问这块代码
    • 每个进入这同步代码块的线程都将能看到之前持有相同锁进入的线程的所做的改动

    对于线程间的可靠通讯及互斥访问 来说,同步是非常必要的

    你可以在定义方法时使用synchronized关键字。这个关键字保证了同一时刻只有一个线程能运行这个方法。其他同样调用了这个方法的线程将被阻塞直到第一个线程离开这个方法。

    public synchronized void critial() {
      // some thread critical stuff
      // here
    }

     你同样也能用synchronized关键字来保护方法中的代码块。这块代码将由一个关键对象来保护,该关键对象可以是个string或其他object。这个关键对象就被称为 lock。所有被相同lock保护的代码在同一时刻只能被单个线程执行。

    举例来说,以下的数据结构将保证同时只有单个线程可以访问add和next方法

    package de.vogella.pagerank.crawler;
    
    import java.util.ArrayList;
    import java.util.List;
    /*** Data structure for a web crawler. Keeps track of the visited sites and keeps 
      * a list of sites which needs still to be crawled. 
      * @author Lars Vogel 
      */
    <pre>public class CrawledSites {
      private List<String> crawledSites = new ArrayList<String>();
      private List<String> linkedSites = new ArrayList<String>();
    
      public void add(String site) {
        synchronized (this) {
          if (!crawledSites.contains(site)) {
            linkedSites.add(site);
          }
        }
      }
    /** * Get next site to crawl. Can return null (if nothing to crawl) */
      public String next() {
        if (linkedSites.size() == 0) {
          return null;
        }
        synchronized (this) {
          <em>// Need to check again if size has changed</em>
          if (linkedSites.size() > 0) {
            String s = linkedSites.get(0);
            linkedSites.remove(0);
            crawledSites.add(s);
            return s;
          }
          return null;
        }
      }
    
    }

     

    3.3. Volatile

    如果一个变量声明时使用了volatile 关键字,那么该关键字保证了,任何读取该变量的线程都将读到最新写进该变量的值。但volatile 关键字不会保证变量上的任何互斥访问

    As of Java 5 write access to a volatile variable will also update non-volatile variables which were modified by the same thread. This can also be used to update values within a reference variable, e.g. for a volatile variable person. In this case you must use a temporary variable person and use the setter to initialize the variable and then assign the temporary variable to the final variable. This will then make the address changes of this variable and the values visible to other threads.

    因为在JAVA 5中,对一个声明了volatile 的变量进行写操作会导致该写操作所在该线程之前所有的对非volatile 变量的修改进行同步更新。这也可用来更新引用类型变量。例如,有个volatile 类型的变量person。你必须创建一个临时变量person,然后调用SETTER方法来初始化这变量然后将临时变量赋值给final变量。 这会使这个变量的地址发生改变并且此变量的值对于其他线程变为可见。

    4. JAVA 内存模型

    4.1. 概览

    JAVA内存模型描述了线程内存与主存间的通讯关系。

    JAVA内存模型定义了线程内的内存改变将怎样传递到其他线程的规则,同样也定义了线程内存与主存进行同步的场景,也描述了哪些操作属于原子操作及操作间的顺序。

    4.2. 原子操作

    一个原子操作是指一个执行时不会被其他操作影响到的最小单位的操作。

    JAVA语言规范保证了对一个变量的读和写操作都是原子的(除了LONG和DOUBLE类型的变量)。对于LONG或DOUBLE类型的变量,只有当这些变量声明时使用了volatile关键字才是原子的

    假设定义了一个INT变量I,那么在java中,I++操作不是一个原子操作。同样,这对于其他数字类型的变量也都不是一个原子操作。

    I++操作先从I中读取了当前值(这是个原子操作)然后再让它加上1写回(原子操作)。但是在读和写这两个操作间,I的值有可能被改变。

    从JAVA1.5起,JAVA提供了原子变量,例如AtomicInteger 或 AtomicLong 都提供了类似 getAndDecrement()getAndIncrement() 及 getAndSet()等原子方法。

    4.3.同步代码块的内存更新

    JAVA内存模型保证了每个进入相同锁同步块的线程都能看到之前进入的其他所有线程修改的结果。

    (全文完)如果您喜欢此文请点赞,分享,评论。

    原文:http://ifeve.com/java-concurrency-cookbook/

10
3
分享到:
评论
1 楼 kaming 2014-05-22  
 

相关推荐

    Java 并发编程实战.pdf

    书中会首先介绍Java并发编程的基础知识,包括线程的创建和运行,同步机制的基本用法,以及Java内存模型的相关概念。随着章节的深入,作者可能会更深入地讲解Java提供的并发工具,例如锁、原子变量、线程池、以及并发...

    《java 并发编程实战高清PDF版》

    总之,《Java并发编程实战》是一本全面介绍Java并发编程的书籍,适合有一定Java基础并希望提升并发编程能力的开发者阅读。通过学习,你可以掌握解决并发问题的策略和技巧,编写出更加健壮和高效的多线程应用。

    java并发编程实战(英文版)

    综上所述,《Java并发编程实战》不仅涵盖了Java并发编程的基础知识和技术细节,还包含了丰富的实践经验和前瞻性的思考,是任何一位从事Java开发工作的程序员不可或缺的学习资源。无论是初学者还是有经验的开发者都能...

    java并发编程书籍

    Java并发编程是软件开发中的一个关键领域,尤其是在大型企业级应用和分布式系统中。通过学习相关的书籍,开发者可以深入...购买并阅读相关的专业书籍,如《Java并发编程实战》等,将有助于你系统地掌握这一领域的知识。

    java并发编程内部分享PPT

    此外,Java并发编程还包括对并发容器的使用,如ArrayList、LinkedList、HashSet、HashMap等基础容器在并发环境下可能存在问题,Java提供了一些线程安全的容器,如Vector、HashTable以及java.util.concurrent包下的...

    java 并发编程的艺术pdf清晰完整版 源码

    通过阅读《Java并发编程的艺术》这本书,开发者不仅可以掌握Java并发编程的基础知识,还能了解到一些高级特性和技巧,从而在实际开发中游刃有余。同时,附带的源码将有助于加深理解,提供实际操作的机会。

    JAVA并发编程实践.pdf+高清版+目录 书籍源码

    《JAVA并发编程实践》这本书是Java开发者深入理解并发编程的重要参考资料。它涵盖了Java并发的核心概念、工具和最佳实践,旨在帮助读者在多线程环境下编写高效、安全的代码。 并发编程是现代软件开发中的关键技能,...

    Java并发编程从入门到精通(pdf)(附源码)

    《Java并发编程从入门到精通》是一本专为Java开发者设计的深度学习并发编程的书籍。作者韩剑锋,凭借其12年的IT行业经验,曾担任多家IT公司的研发总监和技术总监,以其丰富的实战经验和深厚的理论知识,为读者提供了...

    java并发编程与实践

    "Java并发编程与实践"文档深入剖析了这一主题,旨在帮助开发者理解和掌握如何在Java环境中有效地实现并发。 并发是指在单个执行单元(如CPU)中同时执行两个或更多任务的能力。在Java中,这主要通过线程来实现,...

    Java并发编程实践.pdf

    ### Java并发编程实践 #### 一、并发编程基础 ##### 1.1 并发与并行的区别 ...通过上述知识点的学习,我们可以更好地理解和掌握Java并发编程的基本原理和技巧,为开发高效稳定的并发应用程序打下坚实的基础。

    Java并发编程设计原则和模式

    一、并发编程基础 并发是指两个或多个操作在同一时间段内执行,但并不意味着这些操作是并行的,即同时在不同处理器上执行。在Java中,主要通过线程实现并发,线程是操作系统调度的基本单位,每个线程都有自己的程序...

    Java并发编程实战

    第一部分 基础知识 第2章 线程安全性 2.1 什么是线程安全性 2.2 原子性 2.2.1 竞态条件 2.2.2 示例:延迟初始化中的竞态条件 2.2.3 复合操作 2.3 加锁机制 2.3.1 内置锁 2.3.2 重入 2.4 用锁来保护状态 ...

    JAVA并发编程实践

    ### 一、Java并发编程基础 #### 1.1 并发与并行 - **并发**:指在同一时间段内处理多个任务的能力。 - **并行**:指同一时刻处理多个任务的能力。并行依赖于多处理器或多核处理器的支持。 #### 1.2 Java并发工具类...

    13-Java并发编程学习宝典.zip

    Java并发编程是软件开发中的重要领域,特别是在大型系统和高并发场景中不可或缺。"13-Java并发编程学习宝典.zip" 包含了一系列关于Java并发编程的学习资源,旨在帮助开发者掌握多线程编程的核心技术和最佳实践。以下...

    java并发编程实战高清版pdf

    《Java并发编程实战》是Java开发者深入理解和掌握并发编程的一本经典著作...通过阅读《Java并发编程实战》,读者可以深入学习这些知识点,从而更好地应对多线程环境下的编程挑战,编写出更加健壮和高效的Java应用程序。

    JAVA并发编程实践 中文 高清 带书签 完整版 Doug Lea .pdf

    ### 一、Java并发编程基础 #### 1.1 并发与并行的概念 - **并发**:指多个事件在同一时间段内发生。 - **并行**:指多个事件在同一时刻发生。 在Java并发编程中,通常会涉及多个线程共享资源并同时运行的情况,...

    java并发编程艺术

    《Java并发编程艺术》这本书是Java开发者深入理解多线程编程的重要参考资料。它全面而深入地探讨了Java平台上的并发编程技术,对于提升程序性能、优化系统资源利用以及解决多线程环境中的复杂问题有着极大的帮助。...

Global site tag (gtag.js) - Google Analytics