Balking【返回模式】timed【超时模式】
一:balking pattern的参与者
--->GuardedObject(被警戒的对象)

--->该模式的角色:模拟修改警戒对象的线程,当警戒条件达到执行具体操作的线程,参与者(被警戒的参与者)

二:balking pattern模式什么时候使用
--->不需要刻意去执行什么操作的时候(比如说自动保存)
--->不想等待警戒条件成立时。(不让线程休息)
--->警戒条件只有第一次成立时候。

三:balking pattern思考
--->balking pattern (返回模式)和Guarded suspension pattern(等待唤醒模式)的中间
        3.1Guarded suspension当警戒条件不成立时,会等待,直到成立,并被唤醒。
        3.2balking 当警戒条件不成立,退出。
        3.3两种极端的处理方式之间还有一种折衷的做法。在条件成立为止之前,等待一段时间,看看条件是否成立,如果不成立,则balk。这种方式称之为guarded timed 或简单称之为timeOut
---->线程类中的各个唤醒方法
        3.1:当notify方法执行时==>如果wait set里有多条线程,只有一条被唤醒
        3.2:当notifyAll方法执行时==>wait set里有多少条线程都被唤醒。
        3.3:interrupt方法执行时==>wait set里的线程会(与调用notify,notifyAll一样)重新尝试获取锁定。
                                                       ==> notify,notifyAll是对实例调用的,而interrupt是对线程调用的。关于中断,后续会提到。
        3.4:发生timeout时,由于wait(超时时间),和被notify或notifyAll唤醒重新尝试获取锁定,分不清楚,所以timeout需要程序员自己写。

---->sleep和wait的区别有:
  1,这两个方法来自不同的类分别是Thread和Object
  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
   5.wait被唤醒后,重新获取锁,从阻塞的代码处继续往下执行。和sleep一样。

Balking【返回模式】案例:模拟自动保存文件,当文件没有更改时,每隔一秒的自动保存数据,真正保存操作不执行。如果有修改,则执行真正保存操作。

数据类

  1. package com.yeepay.sxf.thread4;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6.  
  7. /**
  8. * 数据类。
  9. * @author sxf
  10. *
  11. */
  12. public class Data {
  13. //文件名
  14. private String fileName;
  15. //文件内容
  16. private String content;
  17. //表示是否被修改过
  18. private boolean flag;
  19. //构造器
  20. public Data(String fileName, String content) {
  21. super();
  22. this.fileName = fileName;
  23. this.content = content;
  24. this.flag=true;
  25. File file =new File(fileName);
  26. try {
  27. file.createNewFile();
  28. FileOutputStream iFileOutputStream=new FileOutputStream(file);
  29. iFileOutputStream.write(content.getBytes());
  30. } catch (IOException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. }
  35. //修改内容
  36. public synchronized void channgeContent(String newContent){
  37. this.content=newContent ;
  38. flag=true;
  39. }
  40.  
  41. //把新的数据写入文件
  42. private void save() throws IOException{
  43. System.out.println("Data.save()"+Thread.currentThread().getName()+"执行写入操作,写入的内容为:"+content);
  44. FileOutputStream fileWriter=new FileOutputStream(new File(fileName));
  45. fileWriter.write(content.getBytes());
  46. }
  47.  
  48. //保存内容
  49. public synchronized void saveNewContent(){
  50. if(!flag){
  51. System.out.println("Data.saveNewContent(试图新保存,但没有更改)");
  52. return;
  53. }
  54. try {
  55. save();
  56. System.out.println("Data.saveNewContent(新内容保存成功)");
  57. flag=false;
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. }
  62. }

模拟修改数据的线程

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 模拟自动修改线程
  4. * @author sxf
  5. *
  6. */
  7. public class ChangeThread implements Runnable{
  8. private Data data;
  9.  
  10. public ChangeThread(Data data) {
  11. super();
  12. this.data = data;
  13. }
  14.  
  15. @Override
  16. public void run() {
  17. for(int i=0;i<20;i++){
  18. //修改内容
  19. System.out.println("ChangeThread.run()"+Thread.currentThread().getName()+"第"+i+"次修改");
  20. data.channgeContent("新内容"+i);
  21. //线程休息10秒
  22. try {
  23. Thread.sleep(10000L);
  24. } catch (InterruptedException e) {
  25. // TODO Auto-generated catch block
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30.  
  31. }

模拟自动保存的线程

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 自动保存的线程
  4. * @author sxf
  5. *
  6. */
  7. public class ZiDongSaveThread implements Runnable{
  8. private Data data;
  9.  
  10. public ZiDongSaveThread(Data data){
  11. this.data=data;
  12. }
  13. @Override
  14. public void run() {
  15. while(true){
  16. //保存数据
  17. data.saveNewContent();
  18. //线程休息1秒,意味着每隔一妙钟自动保存一次文件
  19. try {
  20. Thread.sleep(1000L);
  21. } catch (InterruptedException e) {
  22. // TODO Auto-generated catch block
  23. e.printStackTrace();
  24. }
  25. }
  26.  
  27. }
  28.  
  29. }

测试类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 测试类
  4. * @author sxf
  5. *
  6. */
  7. public class Test {
  8.  
  9. public static void main(String[] args) {
  10. //声明内容
  11. Data data=new Data("/usr/war/hsl.txt", "老黄买了新手机");
  12. //声明自动保存线程
  13. Thread saveThread=new Thread(new ZiDongSaveThread(data));
  14. saveThread.setName("自动保存线程");
  15. //声明模拟修改线程
  16. Thread chaThread=new Thread(new ChangeThread(data));
  17. chaThread.setName("模拟修改线程");
  18.  
  19. //启动线程
  20. saveThread.start();
  21. chaThread.start();
  22.  
  23. }
  24. }

打印结果

Data.save()自动保存线程执行写入操作,写入的内容为:老黄买了新手机
Data.saveNewContent(新内容保存成功)
ChangeThread.run()模拟修改线程第0次修改
Data.save()自动保存线程执行写入操作,写入的内容为:新内容0
Data.saveNewContent(新内容保存成功)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
ChangeThread.run()模拟修改线程第1次修改
Data.save()自动保存线程执行写入操作,写入的内容为:新内容1
Data.saveNewContent(新内容保存成功)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)
Data.saveNewContent(试图新保存,但没有更改)

timed【超时模式】案例:一个线程提供下载数据,另一个线程执行下载,如果有5秒钟以上,提供下载的线程没有提供数据,下载线程因超时异常,停止下载线程运行。

超时异常类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 超时异常类
  4. * @author sxf
  5. *
  6. */
  7. public class TimeOutException extends InterruptedException {
  8.  
  9. public TimeOutException(String msg){
  10. super(msg);
  11. }
  12. }

下载数据的数据类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 下载数据类
  4. * @author sxf
  5. *
  6. */
  7. public class FileData {
  8. //提供下载的数据
  9. private String data;
  10. //有数据可下载
  11. private boolean flag;
  12. //超时时间
  13. private long timeout;
  14.  
  15. //构造器
  16. public FileData(String data, boolean flag, long timeout) {
  17. super();
  18. this.data = data;
  19. this.flag = flag;
  20. this.timeout = timeout;
  21. }
  22.  
  23. //修改状态,唤醒其他所有线程
  24. public synchronized void changeStatus(String data){
  25. this.data=data;
  26. flag=true;
  27. notify();
  28. }
  29.  
  30. //下载操作。如果等timeout/1000秒钟,没有数据供下载,就报超时异常,终止下载
  31. public synchronized void execu() throws InterruptedException{
  32. //开始执行的时间
  33. long start=System.currentTimeMillis();
  34. int i=0;
  35. System.out.println("FileData.execu(开始时间1)");
  36. while (!flag) {
  37. //现在的时间
  38. long now=System.currentTimeMillis();
  39. long reset=timeout-(now-start);
  40. if(reset<=0){
  41. throw new TimeOutException("已经等候"+timeout+"时间了还没有数据可供下载,超时");
  42. }
  43. //如果没有超时,就让下载线程进入wait set,设置超时时间。被唤醒,继续从这里开始执行。
  44. wait(reset);
  45. }
  46. //真正的下载操作
  47. download();
  48. }
  49.  
  50. //真正的下载操作
  51. private void download(){
  52. System.out.println("顺利下载数据==>:"+data);
  53. //下载完之后,将下载状态改为不可下载,等待放入新数据供下载
  54. this.flag=false;
  55. }
  56.  
  57. public String getData() {
  58. return data;
  59. }
  60. public void setData(String data) {
  61. this.data = data;
  62. }
  63. public boolean isFlag() {
  64. return flag;
  65. }
  66. public void setFlag(boolean flag) {
  67. this.flag = flag;
  68. }
  69.  
  70. public long getTimeout() {
  71. return timeout;
  72. }
  73. public void setTimeout(long timeout) {
  74. this.timeout = timeout;
  75. }
  76. }

提供数据供下载的线程类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. *制造数据线程
  4. * @author sxf
  5. *
  6. */
  7. public class GiveDataThread implements Runnable {
  8. //公共数据
  9. private FileData fileData;
  10.  
  11. //构造器
  12. public GiveDataThread(FileData fileData) {
  13. super();
  14. this.fileData = fileData;
  15. }
  16.  
  17. @Override
  18. public void run() {
  19. //制造数据线程,造100个数据
  20. for (int i = 0; i <10; i++) {
  21. fileData.changeStatus("制造数据"+i);
  22. System.out.println("【制造线程制造数据】==》制造数据"+i);
  23. try {
  24. Thread.sleep(1000);
  25. } catch (InterruptedException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. }
  29.  
  30. }
  31.  
  32. }
  33.  
  34. }

下载数据的线程类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 下载线程
  4. * @author sxf
  5. *
  6. */
  7. public class DownLoadThread implements Runnable {
  8. private FileData fileData;
  9. private boolean flag=true;
  10. //构造器
  11. public DownLoadThread(FileData fileData) {
  12. super();
  13. this.fileData = fileData;
  14. }
  15.  
  16. @Override
  17. public void run() {
  18. //开始下载线程
  19. System.out.println("DownLoadThread.run(下载线程开始");
  20. //根据标识
  21. while(flag){
  22. //进行下载
  23. try {
  24. fileData.execu();
  25. } catch (TimeOutException e) {
  26. e.printStackTrace();
  27. flag=false;
  28. }catch (InterruptedException e) {
  29. // TODO: handle exception
  30. System.out.println("DownLoadThread.run(非超时异常)");
  31. }
  32. }
  33.  
  34. System.out.println("DownLoadThread.run(下载线程因为超时,而执行完毕)");
  35. }
  36.  
  37. }

测试类

  1. package com.yeepay.sxf.thread4;
  2. /**
  3. * 测试超时模式
  4. * @author sxf
  5. *
  6. */
  7. public class Test2 {
  8.  
  9. public static void main(String[] args) {
  10. //声明数据类
  11. FileData data=new FileData("sxf",true,5000);
  12. //声明生产数据的线程
  13. Thread giveThread=new Thread(new GiveDataThread(data));
  14. //声明下载数据的线程
  15. Thread downThread=new Thread(new DownLoadThread(data));
  16.  
  17. //启动线程
  18. giveThread.start();
  19. downThread.start();
  20. }
  21. }

打印结果

【制造线程制造数据】==》制造数据0
DownLoadThread.run(下载线程开始
FileData.execu(开始时间1)
顺利下载数据==>:制造数据0
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据1
顺利下载数据==>:制造数据1
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据2
顺利下载数据==>:制造数据2
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据3
顺利下载数据==>:制造数据3
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据4
顺利下载数据==>:制造数据4
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据5
顺利下载数据==>:制造数据5
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据6
顺利下载数据==>:制造数据6
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据7
顺利下载数据==>:制造数据7
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据8
顺利下载数据==>:制造数据8
FileData.execu(开始时间1)
【制造线程制造数据】==》制造数据9
顺利下载数据==>:制造数据9
FileData.execu(开始时间1)
DownLoadThread.run(下载线程因为超时,而执行完毕)
com.yeepay.sxf.thread4.TimeOutException: 已经等候5000时间了还没有数据可供下载,超时
    at com.yeepay.sxf.thread4.FileData.execu(FileData.java:42)
    at com.yeepay.sxf.thread4.DownLoadThread.run(DownLoadThread.java:24)
    at java.lang.Thread.run(Thread.java:662)

多线程程序设计学习(5)balking模式和timed模式的更多相关文章

  1. 多线程程序设计学习(3)immutable pattern模式

    Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个 ...

  2. 多线程程序设计学习(4)guarded suspension模式

    Guarded Suspension[生产消费者模式] 一:guarded suspension的参与者--->guardedObject(被防卫)参与者                1.1该 ...

  3. 多线程程序设计学习(9)worker pattern模式

    Worker pattern[工作模式]一:Worker pattern的参与者--->Client(委托人线程)--->Channel(通道,里边有,存放请求的队列)--->Req ...

  4. 多线程程序设计学习(2)之single threaded execution pattern

    Single Threaded Execution Pattern[独木桥模式] 一:single threaded execution pattern的参与者--->SharedResourc ...

  5. 多线程程序设计学习(6)Producer-Consumer模式

    Producer-Consumer[生产消费者模式]一:Producer-Consumer pattern的参与者--->产品(蛋糕)--->通道(传递蛋糕的桌子)--->生产者线程 ...

  6. 多线程程序设计学习(13)Active Object pattern

    Active Object[接收异步消息的对象] 一:Active Object的参与者--->客户端线程(发起某种操作请求处理)--->代理角色(工头)--->实际执行者(工人)- ...

  7. 多线程程序设计学习(12)Thread-soecific storage pattern

    Thread-Specific-Storage[线程保管箱] 一:Thread-Specific Storage的参与者--->记录日志的线程(ClientThread)--->负责获取不 ...

  8. 多线程程序设计学习(11)Two-phapse-Termination pattern

    Two-phapse-Termination[A终止B线程] 一:Two-phapse-Termination的参与者--->A线程--->B线程 二:Two-phapse-Termina ...

  9. 多线程程序设计学习(10)Future pattern

    Future pattern[订单取货模式] 一:Future pattern的参与者--->Client(客户需求)--->Host(蛋糕门店)--->Data(票据和蛋糕的接口) ...

随机推荐

  1. 高性能网络编程2----TCP消息的发送

    转 陶辉 taohui.org.cn 在上一篇中,我们已经建立好的TCP连接,对应着操作系统分配的1个套接字.操作TCP协议发送数据时,面对的是数据流.通常调用诸如send或者write方法来发送数据 ...

  2. hdu 4869

    一个机智题,可惜比赛的时候没有机智出来 #include<cstdio> #include<cstring> #include<cmath> #include< ...

  3. uva 1056

    floyd 算法 用了stl 的map 存名字的时候比较方便 #include <cstdio> #include <cstdlib> #include <cmath&g ...

  4. Pycharm

    1.下载pycharm-community-3.0.2.exe 2.setting: keymap scheme:快捷键方案,可选择自带的:default:或者选择eclipse的快捷方案. ide ...

  5. PHP Zend Studio9.0怎么把代码搞成和服务器端的同步(就是直接在服务器端修改)

    Zend Studio 可以直接通过Remote System的方式直接连接服务器端的代码,就是可以直接修改服务器端的代码,不过修改的时间小心点,修改就会立即生效的. 选择Remote Systems ...

  6. jquery控制按钮的禁用与启用

    jquery禁用a标签方法1: $(document).ready(function () { $("a").each(function () { var textValue = ...

  7. 2016年2月---Javascript

    How to Learn JavaScript Properly 如何正确学习JavaScript Learn Intermediate and Advanced JavaScript 书籍: < ...

  8. P1023 奶牛的锻炼

    P1023 奶牛的锻炼 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 USACO 描述 奶牛Bessie有N分钟时间跑步,每分钟她可以跑步或者休息.若她在第 ...

  9. linux 防火墙iptables简明教程

    前几天微魔部落再次遭受到个别别有用心的攻击者的攻击,顺便给自己充个电,复习了一下linux下常见的防火墙iptables的一些内容,但是无奈网上的很多教程都较为繁琐,本着简明化学习的目的,微魔为大家剔 ...

  10. ubuntu 折腾之路

    aptitude search :search for the lib...and their realtions. apt-get install :install the app apt-get ...