java 多线程交通信号灯模拟过程详解

这学期我们java课程的课程设计项目----交通信号灯的线程设计

  • 实验目的:多线程设计,同步机制
  • 题意 设计一个交通信号灯类:
    • 变量:位置、颜色(红、黄、绿)、显示时间(秒)。
    • 方法:切换信号灯。
  • 创建并启动两个线程(东西向、南北向)同时运行。
  • 实验要求
    • 设计线程。
    • 设计路口信号灯示意图界面。
    • 进一步将每个方向的信号灯分成3种车道灯:左转、直行和右转。
    • 根据车流量进行时间的模糊控制。

在课程设计的开始并没有仔细看老师的要求,只知道是交通信号灯。然后就开始各种找资料,百度,网上大量的关于红绿灯的设计都是参考张孝祥老师的教程,大概的设计方法是创建了三个类 lamp、road、lampcontrol。

然鹅......对.....然鹅又来了,在查了大概两天资料后,我又反过来看了一遍老师发的设计要求.....这这这.....,光控制灯就行了啊,不要车的啊,捂脸...

所以设计思路马上就变得清晰,根据张老师的做法,每个路口都有三个灯,分别为左转、直行、右转,所以一共有12盏灯。按照要求,右转灯为常亮灯,左转和直行灯才有红绿交替。在除去右转灯的八个灯里面,又可以分为四组可以两两匹配的灯,分别为东西左转南北(平行转垂直)、南北直行(垂直通行)、南北左转东西(垂直转平行)、东西直行(平行通行)。

于是我给这个12个灯编了个号:

emmm 大概就是这样,但是跟生活中的红绿灯不同,生活中的都是看对面路口的灯,我们这里是模拟嘛....就各个路口用各个路口的灯呗.....

大致解释一下,

1号灯为由南向西的左转灯,2号灯为由南向北的直行灯,3号灯为由南向东的右转灯。

4号灯为由东向北的右转灯,5号灯为由东向西的直行灯,6号灯为由东向南的左转灯。

7号灯为由北向西的右转灯,8号灯为由北向南的直行灯,9号灯为由北向东的左转灯。

10号灯为由西向北的左转灯,11号灯为由西向东的直行灯,12号灯为由西向南的右转灯。

然后根据匹配的原则,大概就是这么一张图:

我们就可以得到:

这四组信号灯。

到这里我们思路就很清晰了,我们可以分别为每一组信号灯开一个进程,然后使四个进程循环交替进行就实现了绿灯的转换。使用了程的同步技术。

当然,我们都已经开了四个进程了,为了锦上添花,我当然不介意再加个小车了hhhhhh

实验结果图:

源代码:

light类:

package traffic;
 public class light {
	int x,y;         //灯在画布上的位置
	boolean status;      //灯的状态
	public light(int x,int y,boolean islight) {
		this.x=x;
		this.y=y;
		this.status=islight;
	}
	public void setlight(boolean sta) {    //对外接口更改灯的状态
		this.status=sta;
	}
}

lamp类:

package traffic;
 public class lamp implements Runnable {
	light opposite, now;      //相互匹配的两个灯
	int greentime;         //绿灯亮的时间
	int name;            //编组
	boolean status;         //状态
	static Object lock = new Object();

	public lamp(light l0, light l2,int gt, boolean st, int name) {
		now = l0;
		opposite = l2;
		status = st;
		greentime = gt;
		this.name = name;
		lightstatues();
	}

	public void change() {
		this.status = !(this.status);
		lightstatues();
	}
	public void setgreentime(int time) {
		this.greentime=time;
	}
	public int getgreentime() {
		return this.greentime;
	}
	public void lightstatues() {
		opposite.setlight(status);
		now.setlight(status);
	}

	public void run() {
		while (true) {
			synchronized (lock) {        //使用synchronized实现进程间的互斥
				if (name == mainclass.panel.islight) {      //使用辅助变量实现进程按顺序循环
					//System.out.println("now is: "+name);
					change();
					mainclass.panel.repaint();
					try {
						Thread.sleep(greentime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					lock.notifyAll();        //唤醒其他进程
					change();
					mainclass.panel.LampChange();
					mainclass.panel.repaint();
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} else {
					try {
						lock.wait();      //挂起进程
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}

Mypanel类:

package traffic;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
public class Mypanel extends JPanel {
	light l0,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12;   //十二个灯
	lamp lamp1,lamp2,lamp3,lamp4;           //四组信号灯
	static int islight;                //实现进程循环的辅助变量
	Random r=new Random();
	static public ArrayList<light> lightlist= new ArrayList<light>();  //使用list方便遍历每个灯
	static public ArrayList<car> carlist= new ArrayList<car>();          //方便遍历每个车
	public Mypanel() {
		// TODO Auto-generated constructor stub
		l0=addlist(l0, 212, 316, false);
		l2=addlist(l2, 242, 316, false);
		l3=addlist(l3, 272, 316, true);
		l4=addlist(l4, 316, 116, true);
		l5=addlist(l5, 316, 146, false);
		l6=addlist(l6, 316, 176, false);
		l7=addlist(l7,116 , 70, true);
		l8=addlist(l8, 146, 70, false);
		l9=addlist(l9, 176, 70, false);
		l10=addlist(l10, 70, 212, false);
		l11=addlist(l11, 70, 242, false);
		l12=addlist(l12, 70, 272, true
		lamp1=new lamp(l9,l0,2000,false,0);
		lamp2=new lamp(l11,l5,2000,false,1);
		lamp3=new lamp(l10,l6,2000,false,2);
		lamp4=new lamp(l8,l2,2000,false,3);
 		islight = 0 ;
		Thread t1=new Thread(lamp1);      //创建并启动线程
		Thread t2=new Thread(lamp2);
		Thread t3=new Thread(lamp3);
		Thread t4=new Thread(lamp4);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	light addlist(light a,int x,int y,boolean sta) {
		a=new light(x,y,sta);
		lightlist.add(a);
		return a;
	}
	public void addcar() {          //生成小车
		int now,next;
		now=r.nextInt(4);
		next=r.nextInt(4);
		car testcar=null;
		while(now==next)
			next=r.nextInt(4);
		switch(now) {
		case 0:
			testcar=new car(now,next,l0,l2,l3);
			break;
		case 1:
			testcar=new car(now,next,l6,l5,l4);
			break;
		case 2:
			testcar=new car(now,next,l9,l8,l7);
			break;
		case 3:
			testcar=new car(now,next,l10,l11,l12);
			break;
		}
		carlist.add(testcar);
		Thread catt=new Thread(testcar);
		catt.start();
	}
	public void LampChange() {
		islight=(islight+1)%4;
	}
	public void paint(Graphics g) {
		super.paint(g);

		g.setColor(Color.darkGray);    //画路
		g.fillRect(0, 100, 400, 6);
		g.fillRect(0, 300, 400, 6);
		g.fillRect(100, 0, 6, 400);
		g.fillRect(300, 0, 6, 400);
		g.setColor(Color.gray);
		g.fillRect(0, 200, 400, 2);
		g.fillRect(200, 0, 2, 400);
		g.setColor(Color.blue);
		g.setColor(Color.black);     //画信号灯板
		g.fillRect(202,306, 100, 40);
		g.fillRect(306,106, 40, 100);
		g.fillRect(106,60, 100, 40);
		g.fillRect(60,202,40, 100);
		light temp;
		car buf;
		for(int i=0;i<carlist.size();i++) {   //画车
			buf=carlist.get(i);
			g.setColor(Color.BLUE);
			g.fillRect(buf.x, buf.y, 50, 50);
		}
		for(int i=0;i<lightlist.size();i++) {    //画灯
			temp=lightlist.get(i);
			if(temp.status)
				g.setColor(Color.green);
			else
				g.setColor(Color.RED);
			g.fillOval(temp.x, temp.y, 20, 20);
		}
	}
}

welcomepanel类:

package traffic;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
public class welcomepanel extends JPanel implements Runnable{  //开始界面
	int info = 0;
	Boolean isLive=true;
	public void paint(Graphics g) {
		super.paint(g);
		g.fillRect(0, 0, 420,450);
		g.setColor(Color.red);
		g.setFont(new Font("微软雅黑", Font.BOLD, 30));
		if (info % 2 == 0) {
			g.drawString("多线程红绿灯模拟", 80, 150);
		}
	}

	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			info++;
			this.repaint();
			if (isLive == false) {
				break;
			}
		}
	}
}

set类:

package traffic;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class set extends JFrame implements ActionListener {   //设置界面
  JLabel lab1,lab2,lab3,lab4;
  JTextField jtext1,jtext2,jtext3,jtext4;
  JPanel panel1,panel2,panel3,panel4;
  JButton jb1,jb2;
  int time1,time2,time3,time4;
	public set(){
  	lab1=new JLabel("南北左转东西:");
  	lab2=new JLabel("东西直行:");
  	lab3=new JLabel("东西左转南北:");
  	lab4=new JLabel("南北直行:");
  	time1=mainclass.panel.lamp1.getgreentime();
  	time2=mainclass.panel.lamp2.getgreentime();
  	time3=mainclass.panel.lamp3.getgreentime();
  	time4=mainclass.panel.lamp4.getgreentime();
  	jtext1=new JTextField(String.valueOf(time1));
  	jtext2=new JTextField(String.valueOf(time2));
  	jtext3=new JTextField(String.valueOf(time3));
  	jtext4=new JTextField(String.valueOf(time4));

  	jb1=new JButton("确定");
  	jb1.addActionListener(this);
  	jb2=new JButton("取消");
  	jb2.addActionListener(this);
  	this.setLayout(new GridLayout(5,2,10,5));
  	this.add(lab1);
  	this.add(jtext1);
  	this.add(lab2);
  	this.add(jtext2);
  	this.add(lab3);
  	this.add(jtext3);
  	this.add(lab4);
  	this.add(jtext4);
  	this.add(jb1);
  	this.add(jb2);
  	this.setLocationRelativeTo(null);
  	this.setSize(200, 200);
  	this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  	this.setResizable(false);
    this.setVisible(true);
  }
  public void actionPerformed(ActionEvent e) {
  	if(e.getSource()==jb1) {

  		if(jtext1.getText().length()==0||jtext2.getText().length()==0||jtext3.getText().length()==0||jtext4.getText().length()==0)
  			JOptionPane.showMessageDialog(this, "请输入完整数据!", "错误", JOptionPane.INFORMATION_MESSAGE);
  		else {
  			mainclass.panel.lamp1.setgreentime(Integer.parseInt(jtext1.getText()));
  			mainclass.panel.lamp2.setgreentime(Integer.parseInt(jtext2.getText()));
  			mainclass.panel.lamp3.setgreentime(Integer.parseInt(jtext3.getText()));
  			mainclass.panel.lamp4.setgreentime(Integer.parseInt(jtext4.getText()));
  			this.dispose();
  		}
  	}else if(e.getSource()==jb2){
  		this.dispose();
  	}
  }
}

mainclass主类:

package traffic;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
public class mainclass extends JFrame implements ActionListener{
	static Mypanel panel;
	JMenuBar jmb;
	JMenu jm1, jm2;
	JMenuItem jmi1, jmi2,jmi3,jmi4;
	welcomepanel sp;
	mainclass(){
		this.setTitle("traffic lamp");
		this.setSize(420,450);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jmb=new JMenuBar();
		jm1=new JMenu("控制");
		jm2=new JMenu("设置");
		jmi1=new JMenuItem("开始模拟");
		jmi1.addActionListener(this);
		jmi2=new JMenuItem("退出模拟");
		jmi2.addActionListener(this);
		jmi3=new JMenuItem("随机生成小车");
		jmi3.addActionListener(this);
		jmi4=new JMenuItem("更改绿灯时间");
		jmi4.addActionListener(this);
		jm1.add(jmi1);
		jm1.add(jmi2);
		jm1.add(jmi3);
		jm2.add(jmi4);
		jmb.add(jm1);
		jmb.add(jm2);

		this.setJMenuBar(jmb);

		sp=new welcomepanel();
		Thread t=new Thread(sp);
		t.start();
		this.setContentPane(sp);

		this.setLocationRelativeTo(null);
		this.setResizable(false);
		this.setVisible(true);
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==jmi1) {
			sp.isLive=false;
			this.remove(sp);
			panel = new Mypanel();
			this.setContentPane(panel);
			this.setVisible(true);
		}else if(e.getSource()==jmi2) {
			System.exit(0);
		}else if(e.getSource()==jmi3) {
			if(panel==null)
  			JOptionPane.showMessageDialog(this, "请开始模拟再生成小车", "错误", JOptionPane.INFORMATION_MESSAGE);
			else panel.addcar();
		}else if (e.getSource() == jmi4) {
			if(mainclass.panel==null)
  			JOptionPane.showMessageDialog(this, "请开始模拟再进行设置", "错误", JOptionPane.INFORMATION_MESSAGE);
			else new set();
			}
		}
	public static void main(String[] args) {
		new mainclass();
	}
}

多线程正确性测试:

我们在lamp类的run()方法中添加了一句控制台打印命令,每次进程运行时即会打印此进程的name成员

正确的打印结果应该为 0-1-2-3-4-0-1-2-3-4-.......-1-2-3-....

控制台的输出结果为:

符合预测结果,实验完成!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java多线程编程小实例模拟停车场系统

    下面分享的是一个Java多线程模拟停车场系统的小实例(Java的应用还是很广泛的,哈哈),具体代码如下: Park类 public class Park { boolean []park=new boolean[3]; public boolean equals() { return true; } } Car: public class Car { private String number; private int position=0; public Car(String number)

  • 以银行取钱为例模拟Java多线程同步问题完整代码

    简单了解下在操作系统中进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程.(进程是资源分配的最小单位) 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小.(线程是cpu调度的最小单位) 线程和进程一样分为五个阶段:创建.就绪.运行.阻塞.终止. 多进程是指操作系统能同时运行多个任务(程序). 多线程是指在同一程序中有多个顺序流在执行.首先存钱取钱的这个操作,应该是线程操作的

  • JAVA多线程的使用场景与注意事项总结

    前言 我曾经对自己的小弟说,如果你实在搞不清楚什么时候用HashMap,什么时候用ConcurrentHashMap,那么就用后者,你的代码bug会很少. 他问我:ConcurrentHashMap是什么? -.- 编程不是炫技.大多数情况下,怎么把代码写简单,才是能力. 多线程生来就是复杂的,也是容易出错的.一些难以理解的概念,要规避.本文不讲基础知识,因为你手里就有jdk的源码. 线程 Thread 第一类就是Thread类.大家都知道有两种实现方式.第一可以继承Thread覆盖它的run方

  • Java常见面试题之多线程和高并发详解

    volatile 对 volatile的理解 volatile 是一种轻量级的同步机制. 保证数据可见性 不保证原子性 禁止指令重排序 JMM JMM(Java 内存模型)是一种抽象的概念,描述了一组规则或规范,定义了程序中各个变量的访问方式. JVM运行程序的实体是线程,每个线程创建时 JVM 都会为其创建一个工作内存,是线程的私有数据区域.JMM中规定所有变量都存储在主内存,主内存是共享内存.线程对变量的操作在工作内存中进行,首先将变量从主内存拷贝到工作内存,操作完成后写会主内存.不同线程间

  • java多线程模拟抢红包功能

    今天有朋友问我一道面试题,有5个人抢5个红包,可重复抢,用多线程程序实现,实现方式有多种,分享一下我的思路:应用了阻塞队列的特性. /** * Created by zhanglinqiang on 2016/6/23. */ public class MyTest { public static void main(String[] args) throws InterruptedException { LinkedBlockingQueue<LuckyMoney> luckyMoneys

  • 详解Java多线程处理List数据

    实例1: 解决问题:如何让n个线程顺序遍历含有n个元素的List集合 import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.ArrayUtils; public class Test_4 { /** * 多线程处理list * * @param data 数据list * @param threadNum 线程数 */ public synchronized void handleLi

  • java多线程之火车售票系统模拟实例

    1.前言 为了学习多线程共享与通信,我们模拟一个火车售票系统,假设有10张火车票,三个窗口(也就是三个线程)同时进行售票. 2.非同步代码 package com.tl.skyLine.thread; /** * Created by tl on 17/3/6. */ public class SellTicket { public static void main(String[] args) { TicketWindow tw = new TicketWindow(); Thread t1

  • java多线程学习之死锁的模拟和避免(实例讲解)

    1.死锁 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. Java 死锁产生的四个必要条件: 1.互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用 2.不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放. 3.请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有. 4.循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的

  • java 多线程交通信号灯模拟过程详解

    这学期我们java课程的课程设计项目----交通信号灯的线程设计 实验目的:多线程设计,同步机制 题意 设计一个交通信号灯类: 变量:位置.颜色(红.黄.绿).显示时间(秒). 方法:切换信号灯. 创建并启动两个线程(东西向.南北向)同时运行. 实验要求 设计线程. 设计路口信号灯示意图界面. 进一步将每个方向的信号灯分成3种车道灯:左转.直行和右转. 根据车流量进行时间的模糊控制. 在课程设计的开始并没有仔细看老师的要求,只知道是交通信号灯.然后就开始各种找资料,百度,网上大量的关于红绿灯的设

  • Java多线程之哲学家就餐问题详解

    一.题目 教材提供一个哲学家就餐问题的解决方案的框架.本问题要求通过pthreads 互斥锁来实现这个解决方案. 哲学家 首先创建 5 个哲学家,每个用数字 0~4 来标识.每个哲学家作为一个单独的 线程运行. 可使用 Pthreads 创建线程.哲学家在思考和吃饭之间交替.为了模拟这两种活动,请让线程休眠 1 到 3 秒钟.当哲学家想要吃饭时,他调用函数: pickup_forks(int philosopher _number) 其中,philosopher _number 为想吃饭哲学家的

  • Java多线程中ReentrantLock与Condition详解

    一.ReentrantLock类 1.1什么是reentrantlock java.util.concurrent.lock中的Lock框架是锁定的一个抽象,它允许把锁定的实现作为Java类,而不是作为语言的特性来实现.这就为Lock的多种实现留下了空间,各种实现可能有不同的调度算法.性能特性或者锁定语义.ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,但是添加了类似锁投票.定时锁等候和可中断锁等候的一些特性.此外,它还提供了在激烈争用情况下更

  • java 多线程与并发之volatile详解分析

    目录 CPU.内存.缓存的关系 CPU缓存 什么是CPU缓存 为什么要有多级CPU Cache Java内存模型(Java Memory Model,JMM) JMM导致的并发安全问题 可见性 原子性 有序性 volatile volatile特性 volatile 的实现原理 总结 CPU.内存.缓存的关系 要理解JMM,要先从计算机底层开始,下面是一份大佬的研究报告 计算机在做一些我们平时的基本操作时,需要的响应时间是不一样的!如果我们计算一次a+b所需要的的时间: CPU读取内存获得a,1

  • Java多线程读写锁ReentrantReadWriteLock类详解

    目录 ReentrantReadWriteLock 读读共享 写写互斥 读写互斥 源码分析 写锁的获取与释放 读锁的获取与释放 参考文献 真实的多线程业务开发中,最常用到的逻辑就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务),这样做虽然保证了实例变量的线程安全性,但效率却是非常低下的.所以在JDK中提供了一种读写锁ReentrantReadWriteLock类,使用它可以加快运行效率. 读写锁表示两个锁,一个是读操作相关的锁

  • Java并发编程预防死锁过程详解

    这篇文章主要介绍了Java并发编程预防死锁过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在java并发编程领域已经有技术大咖总结出了发生死锁的条件,只有四个条件都发生时才会出现死锁: 1.互斥,共享资源X和Y只能被一个线程占用 2.占有且等待,线程T1已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X 3.不可抢占,其他线程不能强行抢占线程T1占有的资源 4.循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有

  • java多线程关键字final和static详解

    这篇文章主要介绍了java多线程关键字final和static详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 final关键字 1.final关键字在单线程中的特点: 1)final修饰的静态成员:必须在进行显示初始化或静态代码块赋值,并且仅能赋值一次. 2)final修饰的类成员变量,可以在三个地方进行赋值:显示初始化.构造代码块和构造方法,并且仅能赋值一次. 3)final修饰的局部变量,必须在使用之前进行显示初始化(并不一定要在定义是

  • JAVA DOM解析XML文件过程详解

    这篇文章主要介绍了JAVA DOM解析XML文件过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 代码如下 import java.io.IOException; import javax.xml.parsers.*; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.No

  • Java多线程之搞定最后一公里详解

    目录 绪论 一:线程安全问题 1.1 提出问题 1.2 不安全的原因 1.2.1 原子性 1.2.2 代码"优化" 二:如何解决线程不安全的问题 2.1 通过synchronized关键字 2.2 volatile 三:wait和notify关键字 3.1 wait方法 3.2 notify方法 3.3 wait和sleep对比(面试常考) 四:多线程案例 4.1 饿汉模式单线程 4.2 懒汉模式单线程 4.3 懒汉模式多线程低性能版 4.4懒汉模式-多线程版-二次判断-性能高 总结

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

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

随机推荐