Java多线程同步中的两个特殊类

Java语言内置了synchronized关键字用于对多线程进行同步,大大方便了Java中多线程程序的编写。但是仅仅使用synchronized关键字还不能满足对多线程进行同步的所有需要。大家知道,synchronized仅仅能够对方法或者代码块进行同步,如果我们一个应用需要跨越多个方法进行同步,synchroinzed就不能胜任了。在C++中有很多同步机制,比如信号量、互斥体、临届区等。在Java中也可以在synchronized语言特性的基础上,在更高层次构建这样的同步工具,以方便我们的使用。

当前,广为使用的是由Doug Lea编写的一个Java中同步的工具包,可以在这儿了解更多这个包的详细情况:

http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html

该工具包已经作为JSR166正处于JCP的控制下,即将作为JDK1.5的正式组成部分。本文并不打算详细剖析这个工具包,而是对多种同步机制的一个介绍,同时给出这类同步机制的实例实现,这并不是工业级的实现。但其中会参考Doug Lea的这个同步包中的工业级实现的一些代码片断。

本例中还沿用上篇中的Account类,不过我们这儿编写一个新的ATM类来模拟自动提款机,通过一个ATMTester的类,生成10个ATM线程,同时对John账户进行查询、提款和存款操作。Account类做了一些改动,以便适应本篇的需要:

import java.util.HashMap;
import java.util.Map;
class Account
{
  String name;
  //float amount;
  //使用一个Map模拟持久存储
  static Map storage = new HashMap();
  static
  {
   storage.put("John", new Float(1000.0f));
   storage.put("Mike", new Float(800.0f));
  }
  public Account(String name)
  {
   //System.out.println("new account:" + name);
   this.name = name;
   //this.amount = ((Float)storage.get(name)).floatValue();
  }
  public synchronized void deposit(float amt)
  {
   float amount = ((Float)storage.get(name)).floatValue();
   storage.put(name, new Float(amount + amt));
  }
  public synchronized void withdraw(float amt)
   throws InsufficientBalanceException
   {
    float amount = ((Float)storage.get(name)).floatValue();
    if (amount >= amt) amount -= amt;
    else throw new InsufficientBalanceException();
    storage.put(name, new Float(amount));
   }
  public float getBalance()
  {
   float amount = ((Float)storage.get(name)).floatValue();
   return amount;
  }
}


在新的Account类中,我们采用一个HashMap来存储账户信息。Account由ATM类通过login登录后使用:

public class ATM
{
  Account acc;
  //作为演示,省略了密码验证
  public boolean login(String name)
  {
   if (acc != null) throw new IllegalArgumentException("Already logged in!");
   acc = new Account(name);
   return true;
  }
  public void deposit(float amt)
  {
   acc.deposit(amt);
  }
  public void withdraw(float amt) throws InsufficientBalanceException
  {
   acc.withdraw(amt);
  }
  public float getBalance()
  {
   return acc.getBalance();
  }
  public void logout ()
  {
   acc = null;
  }
}

时间: 2024-10-30 20:35:10

Java多线程同步中的两个特殊类的相关文章

Java多线程编程中的两种常用并发容器讲解_java

ConcurrentHashMap并发容器 ConcurrentHashMap可以做到读取数据不加锁,并且其内部的结构可以让其在进行写操作的时候能够将锁的粒度保持地尽量地小,不用对整个ConcurrentHashMap加锁. ConcurrentHashMap的内部结构 ConcurrentHashMap为了提高本身的并发能力,在内部采用了一个叫做Segment的结构,一个Segment其实就是一个类Hash Table的结构,Segment内部维护了一个链表数组,我们用下面这一幅图来看下Con

Java多线程同步问题的探究(一、线程的先来后到)

众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题. 关于线程的同步,一般有以下解决方法: 1. 在需要同步的方法的方法签名中加入synchronized关键字. 2. 使用synchronized块对需要进行同步的代码段进行同步. 3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象. 另外,为了解决多个线程对同一变量进行访问时可能发生的安全性问题,我们不仅可以采用同步机制,更可以通过JDK 1.2中加入的 ThreadLocal

ava 同步-Java 多线程同步工具 CyclicBarrier

问题描述 Java 多线程同步工具 CyclicBarrier Java中使用CyclicBarrier控制多个线程在执行完后,才执行后续操作,请大家帮我分析下,项目两个代码中为什么执行结果不一样: 代码1. public class CyclicBarrierTest2 { public static void main(String[] args) throws InterruptedException, BrokenBarrierException { final CyclicBarrie

java多线程-同步块实例讲解_java

java多线程-同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java 同步块用来避免竞争.本文介绍以下内容: Java 同步关键字(synchronzied) 实例方法同步 静态方法同步 实例方法中同步块 静态方法中同步块 Java 同步示例 Java 同步关键字(synchronized) Java 中的同步块用 synchronized 标记.同步块在 Java 中是同步在某个对象上.所有同步在一个对象上的同步块在同时只能被一个线程进入并执

Java多线程同步问题的探究(三、Lock来了,大家都让开【1.认识重入锁】)

在上一节中,我们已经了解了Java多线程编程中常用的关键字synchronized,以及与之相关的对象锁机制.这一节中,让我们一起来认 识JDK 5中新引入的并发框架中的锁机制. 我想很多购买了<Java程序员面试宝典>之类图书的朋友一定对下面这个面试题感到非常熟悉: 问:请对比synchronized与java.util.concurrent.locks.Lock 的异同. 答案:主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchroniz

Java多线程同步问题的探究(二、给我一把锁,我能创造一个规矩)

在上一篇中,我们讲到了多线程是如何处理共享资源的,以及保证他们对资源进行互斥访问所依赖的重要机制:对象锁. 本篇中,我们来看一看传统的同步实现方式以及这背后的原理. 很多人都知道,在Java多线程编程中,有一个重要的关键字,synchronized.但是很多人看到这个东西会感到困惑:"都说同步机制是 通过对象锁来实现的,但是这么一个关键字,我也看不出来Java程序锁住了哪个对象阿?" 没错,我一开始也是对这个问题感到困惑和不解.不过还好,我们有下面的这个例程: 1 public cla

java多线程同步的问题

问题描述 java多线程同步的问题 小测试,如何实现变量ticket的同步 private int ticket = 100; public void run() { while(ticket > 0 ) { System.out.println(ticket+" is saled by "+ Thread.currentThread().getName()); ticket--; try { Thread.sleep(200); } catch (InterruptedExce

java多线程同步问题,小弟百撕不得其解,特来求助!

问题描述 java多线程同步问题,小弟百撕不得其解,特来求助! 多线程共享同一资源,同一张票卖出了多张!同步方法,同步代码块都没用. 问题:编写三各类Ticket.SealWindow.TicketSealCenter分别代表票信息.售票窗口.售票中心.售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程. public class ThreadDemo { public static void main(String[] args) { Thread t1

Java多线程编程中synchronized线程同步的教程_java

0.关于线程同步 (1)为什么需要同步多线程?线程的同步是指让多个运行的线程在一起良好地协作,达到让多线程按要求合理地占用释放资源.我们采用Java中的同步代码块和同步方法达到这样的目的.比如这样的解决多线程无固定序执行的问题: public class TwoThreadTest { public static void main(String[] args) { Thread th1= new MyThread1(); Thread th2= new MyThread2(); th1.sta