Java并发编程基础

管理员 52次浏览

摘要: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 com.bill;

import java.util.ArrayList;
import java.util.List;

public class CrawledSites {
  private List crawledSites = new ArrayList();
  private List linkedSites = new ArrayList();

  public void add(String site) {
      synchronized (this) {
          if (!crawledSites.contains(site)) {
              linkedSites.add(site);
          }
      }
  }

  public String next() {
      if (linkedSites.size() == 0) {
          return null;
      }
      synchronized (this) {
          if (linkedSites.size() > 0) {
              String s = linkedSites.get(0);
              linkedSites.remove(0);
              crawledSites.add(s);
              return s;
          }
          return null;
      }
  }

}

表情

共0条评论