zoukankan      html  css  js  c++  java
  • 多线程学习之四返回模式

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

    数据类:

    /**
     * 
     */
    package com.benxq.thread5;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * Created by qucf on 2015年10月22日. 
     */
    public class Data {
    
        //文件名
        private String fileName;
        //文件内容
        private String content;
        //标示是否被修改
        private boolean flag;
        
        //构造器
        public Data(String fileName,String content){
            this.fileName=fileName;
            this.content=content;
            this.flag=true;
            File file=new File(fileName);
            try {
                file.createNewFile();
                FileOutputStream out=new FileOutputStream(file);
                out.write(content.getBytes());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //修改内容
        public synchronized void updateContent(String content){
            this.content=content;
            flag=true;
        }
        //把新内容写入文件
        public void save(){
            System.out.println("线程"+Thread.currentThread().getName()+"执行保存,保存内容为"+content);
            try {
                FileOutputStream out=new FileOutputStream(new File(fileName));
                out.write(content.getBytes());
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
        //保存内容
        public synchronized void saveNewContent(){
            if(!flag){
                System.out.println("线程"+Thread.currentThread().getName()+"试图保存,但内容没有更改");
                return;
            }
            save();
            System.out.println("线程"+Thread.currentThread().getName()+"保存内容成功");
            flag=false;
        }
        
    }
    View Code

    修改内容线程

    /**
     * 
     */
    package com.benxq.thread5;
    
    /**
     * Created by qucf on 2015年10月22日. 
     */
    public class ChangeThread implements Runnable{
        private Data data;
        public ChangeThread(Data data) {
            this.data=data;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println("线程:"+Thread.currentThread().getName()+"第"+i+"次修改");
                data.updateContent("新内容"+i);
                //让线程休息10秒
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }
    View Code

    自动保存线程

    /**
     * 
     */
    package com.benxq.thread5;
    
    /**
     * 模拟保存线程
     * Created by qucf on 2015年10月22日. 
     */
    public class SaveThread implements Runnable{
    
        private Data data;
        public SaveThread(Data data){
            this.data=data;
        }
        
        @Override
        public void run() {
            while(true){
                data.saveNewContent();
                //线程休息1秒
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
    }
    View Code

    主线程

    /**
     * 
     */
    package com.benxq.thread5;
    
    /**
     * Created by qucf on 2015年10月22日. 
     */
    public class Test {
        
        public static void main(String[] args) {
            Data data=new Data("D://thread.txt", "aaa");
            //修改线程
            Thread ut=new Thread(new ChangeThread(data));
            ut.start();
            //保存线程
            Thread save=new Thread(new SaveThread(data));
            save.start();
        }
    
    }
    View Code
  • 相关阅读:
    Chrome自带恐龙小游戏的源码研究(四)
    Chrome自带恐龙小游戏的源码研究(三)
    Chrome自带恐龙小游戏的源码研究(二)
    Chrome自带恐龙小游戏的源码研究(一)
    使用HTML5制作简单的RPG游戏
    EventListener中的handleEvent
    canvas drawImage方法不显示图片的解决方案
    canvas转盘抽奖的实现(二)
    股市高手的领悟
    《最伟大的投资习惯》读书笔记
  • 原文地址:https://www.cnblogs.com/quchengfeng/p/4901802.html
Copyright © 2011-2022 走看看