java多线程之Balking模式介绍

Balk有拒绝,阻碍的意思。如果现在不适合执行这个操作,或者没必要执行这个操作,就停止处理,直接返回。这就是Balking模式。

Balking 模式可以和Guarded Suspension 模式对比,都存在守护条件。而在Balking模式中,如果守护条件不成立就立即中断处理,而Guarded Suspension 模式则是一直等待至可以运行。

创建4个类

名字 说明
Data 表示可以修改并保存的数据的类
SaverThread 定期保存数据内容的类
ChangerThread 修改并保存数据内容的类
Main 测试类
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Data {

    private final  String fileName;
    private String content;
    private boolean changed;

    public Data(String fileName, String content) {
        this.fileName = fileName;
        this.content = content;
    }

    // 修改数据内容
    public synchronized void change(String newContent){
        content = newContent;
        changed = true;
    }

    // 若数据内容修改过。则保存到文件中
    public synchronized void save() throws IOException {
        if (!changed){
            return;
        }
        doSave();
        changed = false;

    }

    // 将数据内容实际保存到文件中
    private void doSave() throws IOException {
        System.out.println(Thread.currentThread().getName() + " calls doSave,content= " + content);
        Writer writer = new FileWriter(fileName);
        writer.write(content);
        writer.close();
    }
}
import java.io.IOException;

public class SaverThread extends  Thread{

    private final Data data;

    public SaverThread(String fileName ,Data data) {
        super(fileName);
        this.data = data;
    }

    @Override
    public void run() {
        try {
            while (true) {
                data.save();   // 要求保存数据
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
import java.util.Random;

public class ChangerThread extends  Thread{

    private  final Data data;
    private  final Random random = new Random();

    public ChangerThread(String name ,Data data) {
        super(name);
        this.data = data;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; true; i++) {
                data.change("No." + i);   // 修改数据
                Thread.sleep(random.nextInt(1000));  // 执行其他操作 ,只是随机暂停一段时间
                data.save();   // 显式的保存
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这里注意Data类的doSava方法每次都是重新创建文件,文件内容会全部消失,该示例不能直接用作应用程序的自动保存功能,如果想做,必须对文件进行备份。

public class Main {
    public static void main(String[] args) {
        Data data =  new Data("data.txt","(empty)");
        new ChangerThread("ChangerThread",data).start();
        new SaverThread("SaverThread",data).start();
    }
}

运行结果:没有出现重复的编号。

Balking 模式中的登场角色

GuardedObject (被保护的对象)

GuardedObject 角色是一个拥有被防护的方法(guardedMethod)的类。当线程执行guardedMethod方法时,若守护条件成立,则执行实际的处理。反之,直接返回。守护条件的成立与否会随着GuardedObject 角色的状态变化而改变。

除了guardedMethod方法外,GuardedObject应该有改变状态的方法(StateChangingMethod)。在上面示例中,由Data扮演此角色,sava方法则是guardedMethod,change方法则是StateChangingMethod。守护条件对应的是change属性为true;

使用场景:

1 并不需要执行时

比如写文件时,如果文件内容没有变化,则无需再写,提高程序性能。

2  不需要等待守护条件成立时

Balking模式的特点就是不进行等待,一旦守护条件不成立时,可以立即返回并进入下一个操作。这能够大大提高程序的相应性。

3 守护条件仅在第一次成立时

例如我们先看看下面的代码

public class Something {
    private boolean initialized =false;
    public synchronized void init(){
        if (initialized){
            return;
        }
        doInit();
        initialized = true;
    }

    private void doInit(){
        // 处理逻辑
    }
}

initialized 表示初始化是否完成,而这里一旦初始化完成,initialized 就为true,而且状态就永远不会发生变化了。所以守护条件不成立时,直接返回。像这种initialized 字段,状态仅变化一次的变量,我们通常称为闭锁。一旦把门锁上了,就再也打不开了。

balk结果的表示方式:当从guardedMethod方法中balk并返回时,有如下表示方式

忽略balk通过返回值来表示balk,如true,false可以通过 异常的方式来表示

总结

到此这篇关于java多线程之Balking模式介绍的文章就介绍到这了,更多相关java多线程Balking模式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java多线程中的Balking模式详解

    目录 1.场景 2.详细说明 3.Balking模式的本质:停止并返回 源代码如下: 总结 1.场景 自动保存功能: 为防止电脑死机,而定期将数据内容保存到文件中的功能. 2.详细说明 当数据内容被修改时,内容才会被保存.即当写入的内容与上次写入的内容一致时,其实就没有必要执行写入操作.也就是说,以”数据内容是否一致”作为守护条件.若数据内容相同,则不执行写入操作,直接返回. 3.Balking模式的本质:停止并返回 如果现在不合适执行该操作,或者没有必要执行该操作,就停止处理,直接返回—-Ba

  • Java多线程模式之Balking模式详解

    本文实例讲述了Java多线程模式之Balking模式.分享给大家供大家参考,具体如下: 当现在不适合这个操作,或是没有必要进行这个操作时就直接放弃这个操作而回去.这个就是Balking模式 例如王某在餐厅吃饭,当王某需要点餐时喊服务员需要点餐.当服务员A和B都注意到了王某点餐的示意,这时服务员B看到服务员A已经去响应了王某的点餐请求,所以服务员B就不会再过去响应王某的点餐请求. 程序示例: 程序的需求是模拟一个自动保存的功能.自动保存是为了预防计算机忽然断电或则软件突然出错的危险,定期将数据保存

  • java多线程之Balking模式介绍

    Balk有拒绝,阻碍的意思.如果现在不适合执行这个操作,或者没必要执行这个操作,就停止处理,直接返回.这就是Balking模式. Balking 模式可以和Guarded Suspension 模式对比,都存在守护条件.而在Balking模式中,如果守护条件不成立就立即中断处理,而Guarded Suspension 模式则是一直等待至可以运行. 创建4个类 名字 说明 Data 表示可以修改并保存的数据的类 SaverThread 定期保存数据内容的类 ChangerThread 修改并保存数

  • Java多线程之FutureTask的介绍及使用

    一.FutureTask的理解 FutureTask属于java.util.concurrent 包:FutureTask表示可取消的异步计算.FutureTask类提供了一个Future的基本实现 ,具有启动和取消计算的方法,查询计算是否完整,并检索计算结果.结果只能在计算完成后才能检索; 如果计算尚未完成,则get方法将阻止. 一旦计算完成,则无法重新启动或取消计算(除非使用runAndReset()调用计算 ). 二.FutureTask类图 从上面的FutureTask类图中可以看出,F

  • Java多线程之volatile关键字及内存屏障实例解析

    前面一篇文章在介绍Java内存模型的三大特性(原子性.可见性.有序性)时,在可见性和有序性中都提到了volatile关键字,那这篇文章就来介绍volatile关键字的内存语义以及实现其特性的内存屏障. volatile是JVM提供的一种最轻量级的同步机制,因为Java内存模型为volatile定义特殊的访问规则,使其可以实现Java内存模型中的两大特性:可见性和有序性.正因为volatile关键字具有这两大特性,所以我们可以使用volatile关键字解决多线程中的某些同步问题. volatile

  • java多线程之Phaser的使用详解

    前面的文章中我们讲到了CyclicBarrier.CountDownLatch的使用,这里再回顾一下CountDownLatch主要用在一个线程等待多个线程执行完毕的情况,而CyclicBarrier用在多个线程互相等待执行完毕的情况. Phaser是java 7 引入的新的并发API.他引入了新的Phaser的概念,我们可以将其看成一个一个的阶段,每个阶段都有需要执行的线程任务,任务执行完毕就进入下一个阶段.所以Phaser特别适合使用在重复执行或者重用的情况. 基本使用 在CyclicBar

  • java多线程之Future和FutureTask使用实例

    Executor框架使用Runnable 作为其基本的任务表示形式.Runnable是一种有局限性的抽象,然后可以写入日志,或者共享的数据结构,但是他不能返回一个值. 许多任务实际上都是存在延迟计算的:执行数据库查询,从网络上获取资源,或者某个复杂耗时的计算.对于这种任务,Callable是一个更好的抽象,他能返回一个值,并可能抛出一个异常.Future表示一个任务的周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务. public interface Callab

  • Java多线程之Park和Unpark原理

    一.基本使用 它们是 LockSupport 类中的方法 // 暂停当前线程 LockSupport.park(); // 恢复某个线程的运行 LockSupport.unpark(暂停线程对象) 应用:先 park 再 unpark Thread t1 = new Thread(() -> { log.debug("start..."); sleep(1); log.debug("park..."); LockSupport.park(); log.debu

  • Java多线程之Disruptor入门

    一.Disruptor简介 Disruptor目前是世界上最快的单机消息队列,由英国外汇交易公司LMAX开发,研发的初衷是解决内存队列的延迟问题(在性能测试中发现竟然与I/O操作处于同样的数量级).基于Disruptor开发的系统单线程能支撑每秒600万订单,2010年在QCon演讲后,获得了业界关注.2011年,企业应用软件专家Martin Fowler专门撰写长文介绍.同年它还获得了Oracle官方的Duke大奖.目前,包括Apache Storm.Camel.Log4j 2在内的很多知名项

  • Java多线程之synchronized关键字的使用

    一.使用在非静态方法上 public synchronized void syzDemo(){ System.out.println(System.currentTimeMillis()); System.out.println("进入synchronized锁:syzDemo"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } 二.使用在静态方法上 publi

  • Java多线程之Interrupt中断线程详解

    一.测试代码 https://gitee.com/zture/spring-test/blob/master/multithreading/src/test/java/cn/diswares/blog/InterruptTests.java 二.测试 为了方便理解简介中 interrupt 的概念, 写个 DEMO 测试一下 /** * 调用 interrupt 并不会影响线程正常运行 */ @Test public void testInvokeInterrupt() throws Inter

  • Java多线程之Future设计模式

    目录 Future -> 代表的是未来的一个凭据 AsynFuture -> Future具体实现类 FutureService -> 桥接Future和FutureTask FutureTask -> 将你的调用逻辑进行了隔离 Future -> 代表的是未来的一个凭据 public interface Future<T> { T get() throws InterruptedException; } AsynFuture -> Future具体实现类

随机推荐