并发编程之基础( 五)

并发编程实战1

  1 package com.dy.xidian;
  2
  3 import java.util.LinkedList;
  4 import java.util.PriorityQueue;
  5 import java.util.Queue;
  6 import java.util.Random;
  7 import java.util.concurrent.ArrayBlockingQueue;
  8 import java.util.concurrent.ExecutorService;
  9 import java.util.concurrent.Executors;
 10 import java.util.concurrent.TimeUnit;
 11
 12 class Customer {
 13     private final int serviceTime;
 14     public Customer(int tm) {
 15         serviceTime = tm;
 16     }
 17     public int getService() {
 18         return serviceTime;
 19     }
 20     public String toString() {
 21         return "[" + serviceTime + "]";
 22     }
 23 }
 24
 25 @SuppressWarnings("serial")
 26 class CustomerLine extends ArrayBlockingQueue<Customer> {
 27
 28     public CustomerLine(int maxLineSize) {
 29         super(maxLineSize);
 30     }
 31
 32     public String toString() {
 33         if (this.size() == 0)
 34             return "[Empty]";
 35         StringBuilder result = new StringBuilder();
 36         for (Customer customer : this)
 37             result.append(customer);
 38         return result.toString();
 39     }
 40
 41 }
 42
 43 class CustomerGenerator implements Runnable {
 44     private CustomerLine customers;
 45     private static Random rand = new Random(47);
 46
 47     public CustomerGenerator(CustomerLine cq) {
 48         customers = cq;
 49     }
 50
 51     @Override
 52     public void run() {
 53         try {
 54             while (!Thread.interrupted()) {
 55                 TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
 56                 customers.put(new Customer(rand.nextInt(1000)));
 57             }
 58         } catch (InterruptedException e) {
 59             System.out.println("CustomerGenerator interrupted!");
 60         }
 61         System.out.println("CustomerGenerator terminating");
 62     }
 63 }
 64
 65 class Teller implements Runnable {
 66     private static int counter = 0;
 67     private final int id = counter++;
 68     private int customerServed = 0;
 69     private CustomerLine customers;
 70     private boolean servingCustomerLine = true;
 71
 72     public Teller(CustomerLine customers) {
 73         super();
 74         this.customers = customers;
 75     }
 76
 77     @Override
 78     public void run() {
 79         try {
 80             while (!Thread.interrupted()) {
 81                 Customer customer = customers.take();
 82                 TimeUnit.MILLISECONDS.sleep(customer.getService());
 83                 synchronized (this) {
 84                     customerServed++;
 85                     while (!servingCustomerLine)
 86                         wait();
 87                 }
 88             }
 89         } catch (InterruptedException e) {
 90             System.out.println(this + "interrupted!");
 91         }
 92         System.out.println(this + "terminating!");
 93     }
 94
 95     public synchronized void doSomethingElse() {
 96         customerServed = 0;
 97         servingCustomerLine = false;
 98     }
 99
100     public synchronized void serveCustomerLine() {
101         assert !servingCustomerLine : "already serving" + this;
102         servingCustomerLine = true;
103         notifyAll();
104     }
105
106     public String toString() {
107         return "Teller " + id + " ";
108     }
109
110     public String shortString() {
111         return "T" + id;
112     }
113
114     public synchronized int compateTo(Teller other) {
115         if (customerServed > other.customerServed)
116             return 1;
117         if (customerServed < other.customerServed)
118             return -1;
119         return 0;
120     }
121 }
122
123 class TellerManger implements Runnable {
124     private ExecutorService exec;
125     private CustomerLine customers;
126     private PriorityQueue<Teller> workingTellers = new PriorityQueue<Teller>();
127     private Queue<Teller> tellersDoingOtherThings = new LinkedList<Teller>();
128     private int adjustmentPeriod;
129
130     public TellerManger(ExecutorService ex, CustomerLine customers,
131             int adjustmentPeriod) {
132         super();
133         this.exec = ex;
134         this.customers = customers;
135         this.adjustmentPeriod = adjustmentPeriod;
136         Teller teller = new Teller(customers);
137         exec.execute(teller);
138         workingTellers.add(teller);
139     }
140
141     public void adjustTellerNumber() {
142         if (customers.size() / workingTellers.size() > 2) {
143             Teller teller = tellersDoingOtherThings.remove();
144             teller.serveCustomerLine();
145             workingTellers.offer(teller);
146             return;
147         }
148         if (workingTellers.size() > 1
149                 && customers.size() / workingTellers.size() < 2)
150             reassignOneTeller();
151         if (customers.size() == 0)
152             while (workingTellers.size() > 1)
153                 reassignOneTeller();
154
155     }
156
157     private void reassignOneTeller() {
158         Teller teller = workingTellers.poll();
159         teller.doSomethingElse();
160         tellersDoingOtherThings.offer(teller);
161     }
162
163     @Override
164     public void run() {
165         try {
166             while (!Thread.interrupted()) {
167                 TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
168                 adjustTellerNumber();
169                 System.out.println(customers + " { ");
170                 for (Teller teller : workingTellers) {
171                     System.out.println(teller.shortString() + " ");
172                 }
173                 System.out.println("}");
174             }
175         } catch (InterruptedException e) {
176             System.out.println(this + "interrupted");
177         }
178         System.out.println(this + "terminating");
179     }
180 }
181
182 public class BankTellerSimulation {
183     static final int MAX_LINE_SIZE = 50;
184     static final int ADJUSTMENT_PERIOD = 1000;
185
186     public static void main(String[] args) throws Exception {
187         ExecutorService exec = Executors.newCachedThreadPool();
188         CustomerLine customers = new CustomerLine(MAX_LINE_SIZE);
189         exec.execute(new CustomerGenerator(customers));
190         exec.execute(new TellerManger(exec, customers, ADJUSTMENT_PERIOD));
191         if (args.length > 0)
192             TimeUnit.SECONDS.sleep(new Integer(args[0]));
193         else {
194             System.out.println("press ‘Enter‘ to quit");
195             System.in.read();
196         }
197         exec.shutdownNow();
198     }
199 }

时间: 2024-10-29 10:46:40

并发编程之基础( 五)的相关文章

高并发编程必备基础 -- 转载自 并发编程网

文章转载自 并发编程网  本文链接地址:高并发编程必备基础 一. 前言 借用Java并发编程实践中的话"编写正确的程序并不容易,而编写正常的并发程序就更难了",相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的,本文算是对多线程情况下同步策略的一个简单介绍. 二. 什么是线程安全问题 线程安全问题是指当多个线程同时读写一个状态变量,并且没有任何同步措施时候,导致脏数据或者其他不可预见的结果的问题.Java中首

并发编程之基础( 四)

新类库 前面已经把并发编程的基础知识讲的差不多了,这章主要介绍一下JAVA中其它一些关于并发编程的类库,主要有一下几个类库. CountDownLatch CyclicBarrier DelayQueue PriorityBlockingQueue ScheduleExecutor Semaphore Exchanger 1. CountDownLatch 该类主要是同步一个或多个任务,强制一个或多个任务等待其它任务执行的一组操作完成.可以给该对象设置一个初始计数值,当计数值不为0时,调用该对象

[书籍翻译] 《JavaScript并发编程》第五章 使用Web Workers

本文是我翻译<JavaScript Concurrency>书籍的第五章 使用Web Workers,该书主要以Promises.Generator.Web workers等技术来讲解JavaScript并发编程方面的实践. 完整书籍翻译地址:https://github.com/yzsunlei/javascript_concurrency_translation .由于能力有限,肯定存在翻译不清楚甚至翻译错误的地方,欢迎朋友们提issue指出,感谢. Web workers在Web浏览器中

并发编程模型基础

并发编程中,有两个关键问题:线程之间如何通信及线程之间如何同步. 通信是指线程之间以何种机制来交换信息.在命令式编程中,线程之间的通信机制有两种,共享内存和消息传递. 在共享内存的并发模型里,线程之间共享程序的公共状态,通过读写内存中的公共状态进行隐式通信:在消息传递的并发模型李,线程之间没有公共状态,线程之间必须通过发送消息来显示进行通信. 同步是指程序中用于控制不同线程间操作发生相对顺序的机制.在共享内存并发模型中,同步是显式进行的,程序员必须显式指定某个方法或某个代码需要在线程之间互斥执行

并发编程 进程基础

操作系统 多道 .分时.实时 同步异步 同步:一件事情完成后再做另一件事 异步:同时做多件事 阻塞和非阻塞 阻塞:recv,accept,recvfrom 会让整个进程进入阻塞队列 非阻塞:进程只会在就绪和 运行状态中切换 进程三状态:就绪 运行 阻塞 并发并行 并发是包含并行的 并发:宏观上多个程序同时运行,实际是同一时间只运运行了一次 并行:微观上多个程序同时运行 子进程和主进程 pid ppid 多并发的tcp服务端 import socket from multiprocessing i

Java 并发编程 --- ThreadPoolExecutor(五)

使用线程池的好处 引用自 http://ifeve.com/java-threadpool/ 的说明: 降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要的等到线程创建就能立即执行. 提高线程的可管理性.线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控. Java中的线程池是用ThreadPoolExecutor类来实现的. 本文就结合JDK 1.8对该类的源码来分析

Java并发编程之美之并发编程线程基础

什么是线程 进程是代码在数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,线程则是进程的一个执行路径,一个进程至少有一个线程,进程的多个线程共享进程的资源. java启动main函数其实就是启动了一个JVM的进程,而main函数所在的线程就是这个进程的一个线程,也称主线程. 进程和线程关系 一个进程有多个线程,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器和栈区域. 程序计数器是一块内存区域,用来记录线程当前要执行的指令地址.如果执行的是native方法,那么pc计

【并发编程必备基础之进程】 -- 2019-08-17 00:04:39

原文: http://blog.gqylpy.com/gqy/236 " 目录 1.操作系统背景知识 2.什么是进程 3.进程调度 4.进程的并行与并发 5.同步异步阻塞非阻塞 6.进程的创建与结束 1.操作系统背景知识 顾名思义,进程即正在执行的一个过程,进程是对正在运行的程序的一个抽象.进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老的最重要的抽象概念之一,操作系统的其他所有内容都是围绕进程的概念展开的. 所以想要真正了解进程,应先了解操作系统,点击进入操作系统介绍

【并发编程必备基础之进程】 -- 2019-08-16 23:57:27

原文: http://blog.gqylpy.com/gqy/236 " 目录 1.操作系统背景知识 2.什么是进程 3.进程调度 4.进程的并行与并发 5.同步异步阻塞非阻塞 6.进程的创建与结束 1.操作系统背景知识 顾名思义,进程即正在执行的一个过程,进程是对正在运行的程序的一个抽象.进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老的最重要的抽象概念之一,操作系统的其他所有内容都是围绕进程的概念展开的. 所以想要真正了解进程,应先了解操作系统,点击进入操作系统介绍