<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="https://iticfly.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://iticfly.github.io/" rel="alternate" type="text/html" /><updated>2019-10-24T09:57:39+08:00</updated><id>https://iticfly.github.io/feed.xml</id><title type="html">振翅终能飞翔</title><subtitle>这是一个忧伤的描述</subtitle><author><name>Zhuang Ma</name></author><entry><title type="html">支付系统账户体系可行性分析</title><link href="https://iticfly.github.io/2019/10/24/gecko-embed/" rel="alternate" type="text/html" title="支付系统账户体系可行性分析" /><published>2019-10-24T00:00:00+08:00</published><updated>2019-10-24T00:00:00+08:00</updated><id>https://iticfly.github.io/2019/10/24/gecko-embed</id><content type="html" xml:base="https://iticfly.github.io/2019/10/24/gecko-embed/">&lt;h1 id=&quot;支付系统账户体系可行性分析&quot;&gt;支付系统账户体系可行性分析&lt;/h1&gt;

&lt;h2 id=&quot;前言&quot;&gt;前言&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;百度百科&lt;/strong&gt;中是这么定义支付的： 支付又称付出、付给，多指&lt;a href=&quot;https://baike.baidu.com/item/付款&quot;&gt;付款&lt;/a&gt;，是发生在购买者和&lt;a href=&quot;https://baike.baidu.com/item/销售/239410&quot;&gt;销售&lt;/a&gt;者之间的金融交换，是社会经济活动所引起的货币&lt;a href=&quot;https://baike.baidu.com/item/债权/6754177&quot;&gt;债权&lt;/a&gt;转移的过程。支付包括交易、&lt;a href=&quot;https://baike.baidu.com/item/清算/7171204&quot;&gt;清算&lt;/a&gt;和&lt;a href=&quot;https://baike.baidu.com/item/结算/1459851&quot;&gt;结算&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;在我看来，一条支付指令中应包含&lt;strong&gt;交易方&lt;/strong&gt;、&lt;strong&gt;对手方&lt;/strong&gt;、以及&lt;strong&gt;订单信息&lt;/strong&gt;(订单编码、交易金额、交收方式、货物详情)。如何有效维护交易双方的支付信息，是支付系统需要考虑的核心设计之一。&lt;/p&gt;

&lt;h2 id=&quot;回顾&quot;&gt;回顾&lt;/h2&gt;

&lt;p&gt;在现有资金清算系统中，主要由付款单和付款单流水两部分组成。其中，交易双方维护信息如下:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;字段名&lt;/th&gt;
      &lt;th&gt;字段描述&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;payerSysUserId&lt;/td&gt;
      &lt;td&gt;交易方平台userId&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerSysUserAccount&lt;/td&gt;
      &lt;td&gt;交易方平台userAccount&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerSysUserName&lt;/td&gt;
      &lt;td&gt;交易方平台userName&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerBankAccName&lt;/td&gt;
      &lt;td&gt;交易方银行账户名&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerBankCardNum&lt;/td&gt;
      &lt;td&gt;交易方银行卡号&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerBankName&lt;/td&gt;
      &lt;td&gt;交易方银行名称&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerBankNo&lt;/td&gt;
      &lt;td&gt;交易方银行编码&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerExBankAccName&lt;/td&gt;
      &lt;td&gt;交易方虚拟账户名&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;payerExBankAccNo&lt;/td&gt;
      &lt;td&gt;交易方虚拟账户号&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;在平台付款单中，需要耦合交易双方的支付信息，以上支付信息，实际上是用户在不同渠道下开通的虚拟账户或平台内部账号信息。同上，在账单模块、以及业务订单模块，也都会维护多种账户耦合信息，这都是费心费力的事情。那么为何不在资金平台内维护用户的账户信息，在清算系统、结算系统、账单系统以及用户对账系统复用账户。&lt;/p&gt;

&lt;h2 id=&quot;账户关联性&quot;&gt;账户关联性&lt;/h2&gt;

&lt;h3 id=&quot;支付指令与支付账户的关联性&quot;&gt;支付指令与支付账户的关联性&lt;/h3&gt;

&lt;h4 id=&quot;渠道支付指令&quot;&gt;渠道支付指令&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/f9a5758eb1ceaf02f83a9d252cdb4e06.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如上所示，账户是支付指令的基础，将账户信息维护在平台内部统一管理，可以保证交易订单有帐可查、有帐可对、有帐可控。&lt;/p&gt;

&lt;h3 id=&quot;用户与支付账户的关联性&quot;&gt;用户与支付账户的关联性&lt;/h3&gt;

&lt;h4 id=&quot;收银台账户管理&quot;&gt;收银台账户管理&lt;/h4&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/c8860de81fbf23cc0ec079dda468e8bf.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;如上所示，支付方式中会展示出满足要求的所有账户列表，这些账户都维护在平台账户模块，可以在账户的控制属性(是否允许支付、是否允许代付、是否冻结)下进行权限分配等信息。&lt;/p&gt;

&lt;h3 id=&quot;对账与支付账户的关联性&quot;&gt;对账与支付账户的关联性&lt;/h3&gt;

&lt;h4 id=&quot;货款账户内部对账&quot;&gt;货款账户内部对账&lt;/h4&gt;

&lt;p&gt;随着货款线上化出入金的推进，账户对账是资金安全的一道重要保障。账户对账的是在账户交易流水上建立的双边对账，主要对账户的日终余额和日交易进行对账处理，这些都是建立在账户体系下实现的。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/fda66943aa3a2615bde78e0d87b5fd1a.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;账单与支付账户的关联性&quot;&gt;账单与支付账户的关联性&lt;/h3&gt;

&lt;h4 id=&quot;交易明细来源追踪&quot;&gt;交易明细来源追踪&lt;/h4&gt;

&lt;p&gt;目前账单信息直接与平台用户信息、付款账号关联，关联数据较单一，且存在耦合字段较多，不利于业务和代码维护。让账单信息直接与账户关联，通过多表关联查询，可以有效解决这一问题。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/e1b5c9af9682a396cfe934300e11ad5c.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;小结&quot;&gt;小结&lt;/h2&gt;

&lt;p&gt;这是一个没有小结的小结。&lt;/p&gt;</content><author><name>Zhuang Ma</name></author><summary type="html">支付系统账户体系可行性分析</summary></entry><entry><title type="html">中农网资金安全治理之对账体系建设</title><link href="https://iticfly.github.io/2019/10/08/gecko-embed/" rel="alternate" type="text/html" title="中农网资金安全治理之对账体系建设" /><published>2019-10-08T00:00:00+08:00</published><updated>2019-10-08T00:00:00+08:00</updated><id>https://iticfly.github.io/2019/10/08/gecko-embed</id><content type="html" xml:base="https://iticfly.github.io/2019/10/08/gecko-embed/">&lt;h1 id=&quot;中农网资金安全治理之对账体系建设&quot;&gt;中农网资金安全治理之对账体系建设&lt;/h1&gt;

&lt;h2 id=&quot;前言&quot;&gt;前言&lt;/h2&gt;

&lt;p&gt;随着中农网支付业务的飞速发展，每天产生的资金额已经达到上百万，清结算系统在保证线上服务稳定可靠的前提下，如何系统化的保障资金安全是非常核心且重要的课题，支付清结算系统经过不断地建设和打磨，在资金安全保障的多个方面均有一些总结和实践，保障资金安全是值得系统思考的课题，只言片语难以全面概括，需要更多的着墨才能较完整阐述，本文侧重点会阐述“对账”的概念，在支付&amp;amp;清结算领域，这是一个非常重要的专业名词，下文将介绍“对账”在分布式系统建设中的实践和解决方案，力求在系统覆盖度、资金准确性、时效等多个维度为系统资金安全保驾护航，实现更健壮可靠的资金履约。&lt;/p&gt;

&lt;h2 id=&quot;背景问题&quot;&gt;背景&amp;amp;问题&lt;/h2&gt;

&lt;p&gt;随着中农网支付事业的蓬勃发展，支付清结算业务的复杂性也在不断的增高，总结起来，主要有以下几个特点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;场景多&lt;/strong&gt;:包括鲜茧采购、线上虚拟户金额划转、线上诚意金划转、线上货款划转、ERP结算中心、OMS订单中心等多条业务线；对接多个业务系统。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;链路长&lt;/strong&gt;:清结算内部经历记账、汇总账单、付款、回执下载等多个流程。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;交易金额大&lt;/strong&gt;：目前日交易额已经达到百万级别，并不断增加中。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;第三方支付通道不稳定&lt;/strong&gt;：对接的第三方服务在并发场景下支付成功率无法保证到2个9。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在这样的业务背景下，我们的系统可谓险象环生。因业务高度复杂，稍有不慎就会出现问题，面对大量的日单量，同时还要确保结算金额的准确，这就让我们对问题的容忍度变得极低。这也给我们的资金安全保障造成了巨大的挑战。下面我们列举了一些系统日常运行过程中出现的问题。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;场景1：加盟商(如 鲜茧采购)核对账单，发现少了一笔费用。&lt;br /&gt;原因：结算单推动平台账单服务账单数据时，数据推送失败并丢失。&lt;/th&gt;
      &lt;th&gt;场景2：中农网资金平台线上订单状态变更支付成功，实际支付结果为未支付。&lt;br /&gt;原因：第三方支付渠道内线上支付结果与实际支付结果状态不一致。&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;场景3：结算已发起付款，但订单状态一直为支付中。&lt;br /&gt;原因：支付服务负载过高、支付排队队列阻塞等导致订单数据未能推送至银行。&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;场景4：拉取业务支付数据，出现订单重复支付问题。&lt;br /&gt;原因：接口问题、数据重算导致重复推送资金平台。&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;可以看出，这些都是一些上下游交互的边界场景下遇到的问题。当然不仅限于这些场景，凡是有系统交互、数据交互边界的场景，都会出现此类问题，我们称之为“一致性问题”。经粗略统计，我们清结算系统建立以来有70%左右的问题都属于一致性问题。&lt;/p&gt;

&lt;p&gt;导致一致性问题的原因有很多，诸如：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;幂等、并发控制不当。&lt;/li&gt;
    &lt;li&gt;基础环境故障：比如网络、数据库、消息中间将发生故障。&lt;/li&gt;
    &lt;li&gt;其他代码bug。&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;目前支付模块的日结算金额已达到百万级别，每个一致性问题都有可能给中农网造成巨大的损失。因此如何解决系统的一致性问题成为我们保障资金安全的重中之重。关于一致性问题，业内已经论述的非常成熟了，搜索引擎中搜索“一致性问题”，随处可见此概念的定义、问题阐述、意义以及解决思路，诸如：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ul&gt;
    &lt;li&gt;强一致性协议: 两阶段提交、三阶段提交、TCC (Try-Confirm-Cancel)等&lt;/li&gt;
    &lt;li&gt;最终一致性: 主动轮询、异步确保、可靠消息、消息事务等&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;这些手段的目标都是在事中避免问题的发生。但是在实际场景中，无论是系统的内部逻辑还是外部环境都十分复杂多变、不可预知，我们很难完全避免问题。因此事后对于问题数据的发现以及修复就显得尤为重要。这些也正是我们这篇文章要论述的“对账”的核心使命。我们力求总结对账领域内最专业的思路和方法，并结合自身的业务特点，建设配送清结算的对账体系，构筑配送资金安全的坚固防线。在系统的整个构建过程中我们主要围绕以下几个目标：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;场景覆盖的完整性：无死角覆盖清结算业务涉及的各个场景。&lt;/li&gt;
  &lt;li&gt;问题发现的准确性：能够准确的发现问题，保证不漏报，不误报。&lt;/li&gt;
  &lt;li&gt;问题处理的实时性：尽可能缩短问题处理的周期，极力避免可能造成的损失。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下面开始正式介绍中农网支付清结算对账体系的构建经验。&lt;/p&gt;

&lt;h2 id=&quot;对账的定义&quot;&gt;对账的定义&lt;/h2&gt;

&lt;p&gt;对账的概念随着金融、互联网行业的发展，定义上也经历了几个阶段的变化，如下：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;stage 1 ：对账最初来源于&lt;strong&gt;会计核算&lt;/strong&gt;，是为保证账簿记录正确可靠，对账簿中的相关数据进行检查和核对的工作。&lt;/li&gt;
  &lt;li&gt;stage 2 ：随着&lt;strong&gt;互联网金融或电商&lt;/strong&gt;行业的发展，对账也扩大了应用范围，这一时期，对账是指在固定周期内，支付使用方和支付提供方（银行和第三方支付）相互确认交易、资金的正确性，保证双方的交易、资金一致正确。&lt;/li&gt;
  &lt;li&gt;stage 3 ：从广义来看，&lt;strong&gt;所有的跨端系统&lt;/strong&gt;之间的数据核对都应该叫对账，主要是检查和发现数据在流转过程中的不一致问题。通常分为信息流的核对和资金流的核对。信息流核对主要是对业务数据之间的核对，资金流是对资金交易数据进行核对。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;系统概况&quot;&gt;系统概况&lt;/h2&gt;

&lt;p&gt;清结算中心作为资金交付落地的中转中心,上游对接了类似鲜茧采购,ERP结算系统,OMS订单系统,虚拟户划转等外部系统,下游又对接了如茧丝-众邦支付,白糖-中信支付,茧丝-货款等多个支付渠道,不仅承上启下,而且同时对接处理多种信息流数据,系统的高度复杂性给对账的全面性和准确性造成了极大的困难,如图:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/a8b7a5b49e24da1864dadc73827d8b2f.jpg&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/a8b7a5b49e24da1864dadc73827d8b2f.jpg&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;设计思路&quot;&gt;设计思路&lt;/h2&gt;

&lt;p&gt;从整体来看，按照时序维度的先后，系统对账主要分为三阶段的工作。分别是&lt;strong&gt;数据准备&lt;/strong&gt;、&lt;strong&gt;数据核对&lt;/strong&gt;和&lt;strong&gt;差错处理&lt;/strong&gt;。在对账专业概念中，数据核对和差错处理又叫&lt;strong&gt;轧账&lt;/strong&gt;和&lt;strong&gt;平账&lt;/strong&gt;。三个环节紧密相连，从前期准备、问题发现、问题处理三个角度展开对账工作。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/bc86ff01f5b77705359852eb1d560e39.png&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/bc86ff01f5b77705359852eb1d560e39.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;数据准备&quot;&gt;数据准备&lt;/h3&gt;

&lt;p&gt;在数据接入层，不同的第三方渠道会提供不同的数据接入方式。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;数据拉取:我们主动拉取数据，如ftp拉取csv或接口方式下载账单文件。如众邦银行；&lt;/li&gt;
  &lt;li&gt;文件上传：我们主动将账单文件推送至第三方文件服务器，由第三方对账单数据进行解析。如中信银行；&lt;/li&gt;
  &lt;li&gt;数据推送:接入方将数据通过ETL(Extract-Transform-Load)推送到第三方数据仓库，由第三方对账单数据解析。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/3906ed666b8dc8db8ec79a59de70ee94.png&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/3906ed666b8dc8db8ec79a59de70ee94.png&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;数据核对轧账&quot;&gt;数据核对（轧账）&lt;/h3&gt;

&lt;h4 id=&quot;1对账批次&quot;&gt;1.对账批次&lt;/h4&gt;

&lt;p&gt;一个批次代表一次对账操作，批次信息下会展示交易日单数、日交易额以及差错和缓冲数量。目前一个第三方渠道下一个批次；&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/d2c2f8fd4f305721778fd13267dee975.jpg&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/d2c2f8fd4f305721778fd13267dee975.jpg&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;2对账缓存&quot;&gt;2.对账缓存&lt;/h4&gt;

&lt;p&gt;对于平台支付成功但第三方渠道账单中不存在的流水记录，默认置于缓存池(最大缓存日期3天)。同时，缓存池中的数据也可被n+1日第三方渠道账单匹配。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/3289d7b721943d31f13d2257f125ed36.jpg&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/3289d7b721943d31f13d2257f125ed36.jpg&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;3对账方式&quot;&gt;3.对账方式&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;双边对账&lt;/strong&gt;:以双方的数据互为基准对账。既要保证结算数据为成功的，支付平台也要成功，又要保证支付平台数据为成功的，结算数据也要成功。&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;4对账粒度&quot;&gt;4.对账粒度&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;明细对账：对双方的每条数据进行匹配，包括订单编号、交易金额、手续费金额等。清结算平台自定义出&lt;strong&gt;银行漏单、平台漏单、平台状态不符、平台短款、平台长款&lt;/strong&gt;这几种差错类型。&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/f72cc8dd39f1713d5eaee7a3f6b7fbdf.jpg&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/f72cc8dd39f1713d5eaee7a3f6b7fbdf.jpg&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;5银行账单列表&quot;&gt;5.银行账单列表&lt;/h4&gt;

&lt;p&gt;对每一个批次下第三方渠道的账单文件下载，解析为清结算统一识别适配的账单文件。方便在页面对数据进行比对、排错。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/aee4a6eea3f039f4a93807e8f0de0ac7.jpg&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/aee4a6eea3f039f4a93807e8f0de0ac7.jpg&quot; /&gt;&lt;/p&gt;

&lt;h4 id=&quot;6对账时机&quot;&gt;6.对账时机&lt;/h4&gt;

&lt;p&gt;不同的第三方渠道下对账策略不一样，需要根据定时任务手动适配不同渠道下对账时机。如众邦银行适配为n+1日12：00开始对账操作。&lt;/p&gt;

&lt;h3 id=&quot;差错处理平帐&quot;&gt;差错处理（平帐）&lt;/h3&gt;

&lt;p&gt;差错处理主要是对数据核对过程中发现的问题数据进行处理。我们会建立一个统一结构的差错记录，将数据核对发现的问题进行统一存储。差错记录中的数据会进行二次核对，避免由于日切等原因造成的问题错报。对于那些真实存在问题的数据我们会提供两种解决模式，如果是常见的问题，且有一套标准的解决方案的话，我们会把它系统化，采取系统自动修复的方式；如果系统无法自动修复，那么我们会进行系统报警，并进行人工处理。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/fd3d6097da4ac0b4ce010e40696f203c.png&quot; alt=&quot;https://magpie-pic.oss-cn-shenzhen.aliyuncs.com/fd3d6097da4ac0b4ce010e40696f203c.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;小结&quot;&gt;小结&lt;/h2&gt;

&lt;p&gt;这是一个没有小结的小结。-_-&lt;/p&gt;</content><author><name>Zhuang Ma</name></author><summary type="html">中农网资金安全治理之对账体系建设</summary></entry><entry><title type="html">等待通知机制之wait()/notify()</title><link href="https://iticfly.github.io/2019/09/16/gecko-embed/" rel="alternate" type="text/html" title="等待通知机制之wait()/notify()" /><published>2019-09-16T00:00:00+08:00</published><updated>2019-09-16T00:00:00+08:00</updated><id>https://iticfly.github.io/2019/09/16/gecko-embed</id><content type="html" xml:base="https://iticfly.github.io/2019/09/16/gecko-embed/">&lt;h1 id=&quot;等待通知机制之waitnotify&quot;&gt;等待通知机制之wait()/notify()&lt;/h1&gt;

&lt;h2 id=&quot;1waitnotify官方定义&quot;&gt;1.wait()/notify官方定义&lt;/h2&gt;

&lt;p&gt;wait()/notify是Object类中方法，且定义为final级别(不可修改).&lt;/p&gt;

&lt;p&gt;jdk8中对wait()的注释为&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;使当前线程等待，直到另一个线程为此对象调用&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@link&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;＃&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法或&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@link&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;＃&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notifyAll&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;换句话说，此方法的行为就像它只是&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;执行调用&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;一样。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;当前线程必须拥有此对象的监视器。线程&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;释放此监视器的所有权并等待，直到另一个线程&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;通过调用&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法或&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notifyAll&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法通知等待此对象监视器的线程唤醒&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;。然后线程等待，直到它可以&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;重新获得监视器的所有权并继续执行。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;与在一个参数版本中一样，中断和虚假唤醒是&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;可能的，并且此方法应始终在循环中使用：&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pre&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;synchronized&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;condition&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//执行适合条件的操作*} * &amp;lt;/ pre&amp;gt; *此方法只能由作为此对象监视器的所有者*的线程调用。有关线程可以成为监视器所有者的方式的*描述，请参阅{@code notify}方法。 * * @throws IllegalMonitorStateException如果当前线程不是对象监视器的所有者。 * @throws InterruptedException如果任何线程在当前线程*等待通知之前或当前线程中断*当前线程。当抛出此异常时，将清除当前线程的&amp;lt;i&amp;gt;中断*状态&amp;lt;/ i&amp;gt;。 * @see java.lang.Object＃notify（）* @see java.lang.Object＃notifyAll（）* /&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;jdk8中对notify()的注释为&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;唤醒正在等待此对象的&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;监视器的单个线程。如果任何线程正在等待此对象，则选择其中一个&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;被唤醒。选择是任意的，由&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;实施自行决定。线程通过调用&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法之一等待对象的&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;监视器。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;唤醒的线程将无法继续，直到当前&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;线程放弃对此对象的锁定。唤醒的线程将以通常的方式与可能&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;主动竞争同步此对象的任何其他线程竞争&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;例如，&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;唤醒线程在&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;下一个锁定此对象的线程中没有可靠的特权或劣势。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;此方法只能由作为此对象监视器的所有者&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;的线程调用。线程以三种方式之一成为&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;对象监视器的所有者：&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;通过执行该对象的同步实例方法。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;通过执行在对象上同步的&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;synchronized&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;语句&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;的主体。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;对于&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;，&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;类型的对象，通过执行该类的&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;synchronized&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;静态方法。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;一次只能有一个线程拥有对象的监视器。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IllegalMonitorStateException&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;如果当前线程不是此对象监视器的所有者。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@see&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;＃&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notifyAll&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@see&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;jdk8中对notifyAll()的注释为&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;唤醒等待此对象监视器的所有线程。&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;线程通过调用&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法之一等待对象的监视器。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;唤醒的线程将无法继续，直到当前&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;线程放弃此对象上的锁定。唤醒的线程&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;将以通常的方式与可能&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;主动竞争同步此对象的任何其他线程竞争&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;例如，&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;被唤醒的线程在下一个锁定此对象的线程中没有可靠的特权或劣势。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;此方法只能由作为此对象监视器的所有者&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;的线程调用。有关线程可以成为监视器所有者的方式的&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;描述，请参阅&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;方法。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IllegalMonitorStateException&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;如果当前线程不是此对象监视器的所有者。&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@see&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;＃&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nd&quot;&gt;@see&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;（）&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2wait和sleep的区别&quot;&gt;2.wait()和sleep()的区别&lt;/h2&gt;

&lt;p&gt;-wait是object类的方法，sleep是Thread的方法。&lt;/p&gt;

&lt;p&gt;-wait方法必须在同步上下文中使用(如synchronized)，会使当前线程释放对象的内置锁并等待，使得当前线程阻塞，直到其他线程唤醒当前线程。sleep方法会使当前线程休眠，是基于Thread的方法，并不会释放调用对象的锁，直到休眠结束重新获得对象锁。&lt;/p&gt;

&lt;h2 id=&quot;3notifynotifyall的作用&quot;&gt;3.notify()/notifyAll()的作用&lt;/h2&gt;

&lt;p&gt;notify是通知一个线程获取对象内置锁，notifyAll是唤醒等待此对象内置锁的所有线程，如果当前线程不是此对象内置锁的所有者，会抛出IllegalMonitorStateException。&lt;/p&gt;

&lt;p&gt;被唤醒的线程无法立即执行，必须等待唤醒线程释放对象内置锁。&lt;/p&gt;

&lt;h2 id=&quot;4等待通知之交叉打印奇偶数&quot;&gt;4.等待通知之交叉打印奇偶数&lt;/h2&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OuNum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;t1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;偶数&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JiNum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;t2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;奇数&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;t1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;t2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;OuNum&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Runnable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;OuNum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kd&quot;&gt;synchronized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;偶数线程抢到锁了&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currentThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+-+偶数&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;

                        &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;偶数线程开始阻塞&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;偶数线程阻塞结束&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;printStackTrace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JiNum&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Runnable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;JiNum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kd&quot;&gt;synchronized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;奇数线程抢到锁了&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currentThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;+-+奇数&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++;&lt;/span&gt;

                        &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;flag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;notify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;奇数线程开始阻塞&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;TwoThreadWaitNotify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                            &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;奇数线程阻塞结束&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;printStackTrace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;输出结果如下:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;偶数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程开始阻塞&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程开始阻塞&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程阻塞结束&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;偶数&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程开始阻塞&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程阻塞结束&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程开始阻塞&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程阻塞结束&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;偶数&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;偶数线程开始阻塞&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程阻塞结束&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数线程抢到锁了&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-+&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;奇数&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;5小结&quot;&gt;5.小结&lt;/h2&gt;

&lt;p&gt;notify以及wait方法作为基类object原生方法，和jvm中对象管理机制有一定关系。实例对象内部会含有一个内置锁(在jdk注释处可能描述为monitor)，jvm控制内置锁与线程之前的绑定关系，控制线程的执行与等待。所以，要想深入了解其中的运行原理，还需对jvm有一定的了解与深入。&lt;/p&gt;</content><author><name>Zhuang Ma</name></author><summary type="html">等待通知机制之wait()/notify()</summary></entry><entry><title type="html">设计模式-代理模式</title><link href="https://iticfly.github.io/2019/03/18/gecko-embed/" rel="alternate" type="text/html" title="设计模式-代理模式" /><published>2019-03-18T00:00:00+08:00</published><updated>2019-03-18T00:00:00+08:00</updated><id>https://iticfly.github.io/2019/03/18/gecko-embed</id><content type="html" xml:base="https://iticfly.github.io/2019/03/18/gecko-embed/">&lt;p&gt;&lt;strong&gt;代理(Proxy)&lt;/strong&gt;是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;应用场景&lt;/strong&gt;：为其他对象提供一种代理以控制对这个对象的访问。从结构上来看和 Decorator 模式类似，
但 Proxy 是控制，更像是一种对功能的限制，而 Decorator 是覆盖或者增加职责。
Spring 的 Proxy 模式在 AOP 中有体现，比如 JdkDynamicAopProxy 和 Cglib2AopProxy。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;归类&lt;/th&gt;
      &lt;th&gt;特点&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;穷举&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;结构型模式&lt;/td&gt;
      &lt;td&gt;执行者、代理人&lt;br /&gt;对于被代理人来说，这件事一定要做的。但是我自己又不想做或者没时间做&lt;br /&gt;对于代理人而言，需要获取到被代理人的资料，只是参与整个过程的某个或几个环节&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;租房中介、售票黄牛、婚介、事务代理、非侵入式日志监听&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;使用代理模式主要有两个目的&lt;strong&gt;:一是保护目标对象，二是增强目标对象。&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;静态代理&quot;&gt;&lt;strong&gt;静态代理&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;举个例子：人到了适婚年龄，父母总是迫不及待希望早点抱孙子。而现在社会的人在各
种压力之下，都选择晚婚晚育。于是着急的父母就开始到处为自己的子女相亲，比子女
自己还着急。这个相亲的过程，就是一种我们人人都有份的代理。来看代码实现：&lt;/p&gt;

&lt;p&gt;顶层接口 Person：&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/**
     * 相亲
     */&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;儿子要找对象,实现Son类:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Son&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;儿子要求:肤白貌美大长腿&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;父亲要帮儿子相亲,实现Father(可怜天下老父亲-_-)&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Father&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Son&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;son&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Father&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Son&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;son&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;son&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;son&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;父母物色对象&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;son&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;双方同意交往,确立交往&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;来看测试代码:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Father&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;father&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Father&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Son&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;father&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;运行结果:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;父母物色对象
儿子要求:肤白貌美大长腿
双方同意交往,确立交往
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;在上述场景中,父亲作为执行者，儿子作为被代理者，对外是父亲(执行者)帮儿子(代理对象)相亲，保护了儿子(代理对象)&lt;strong&gt;不对外暴露&lt;/strong&gt;，同时也对儿子(代理对象)的相亲行为做了前置增强和后置增强(&lt;strong&gt;功能增强&lt;/strong&gt;)。&lt;/p&gt;

&lt;p&gt;对于分布式业务场景中,我们通常会对数据库进行分库分表，在对数据进行操作之前便可以进行前置设置数据源。&lt;/p&gt;

&lt;h2 id=&quot;动态代理&quot;&gt;动态代理&lt;/h2&gt;

&lt;h4 id=&quot;jdk动态代理&quot;&gt;JDK动态代理&lt;/h4&gt;

&lt;p&gt;动态代理和静态对比基本思路是一致的，只不过动态代理功能更加强大，随着业务的扩
展适应性更强。如果还以找对象为例，使用动态代理相当于是能够适应复杂的业务场景。
不仅仅只是父亲给儿子找对象，如果找对象这项业务发展成了一个产业，进而出现了媒
婆、婚介所等这样的形式。那么，此时用静态代理成本就更大了，需要一个更加通用的
解决方案，要满足任何单身人士找对象的需求。我们升级一下代码，先来看 JDK 实现方
式：&lt;/p&gt;

&lt;p&gt;创建媒婆(婚介)JDKMeipo类:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JDKMeipo&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;InvocationHandler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;?&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clazz&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Proxy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newProxyInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clazz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClassLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;clazz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInterfaces&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proxy&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Method&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Throwable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;after&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;before&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;我是媒婆,我已经拿到你的需求了...&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;开始物色...&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;after&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;如果合适的话,就准备办事...&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;创建客户Customer类:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Customer&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;我是客户,我的要求是白富美...&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;测试类:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DynamicProxyTest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JDKMeipo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;findLove&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;测试输出:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我是媒婆,我已经拿到你的需求了...
开始物色...
我是客户,我的要求是白富美...
如果合适的话,就准备办事...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;用户只要是进行相亲行为,都可以在媒婆(JDKMeipo)处创建代理对象,执行者便可以对代理对象的行为进行增强操作。&lt;/p&gt;

&lt;p&gt;JDK  Proxy 采用字节重组，重新生成的对象来替换原始的对象以达到动态代理的效果。JDK Proxy生成对象的步骤如下:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;拿到被代理对象的引用，并且通过反射的方式获取到它所实现的所有接口。&lt;/li&gt;
  &lt;li&gt;JDK Proxy 重新生成一个新类，同时新类要实现被代理类所实现的所有接口。&lt;/li&gt;
  &lt;li&gt;动态生成 Java 代码，把新加的业务逻辑方法由一定的逻辑代码去维护。&lt;/li&gt;
  &lt;li&gt;编译新生成的 Java 代码.class。&lt;/li&gt;
  &lt;li&gt;再重新加载到 JVM 中运行。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;以上这个过程就叫字节码重组。JDK 中有一个规范，在 ClassPath 下只要是以 $  开头的 class 文件一般是自动生成的。&lt;/p&gt;</content><author><name>Zhuang Ma</name></author><summary type="html">代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能. 这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。</summary></entry><entry><title type="html">记第一篇博客</title><link href="https://iticfly.github.io/2019/03/15/gecko-embed/" rel="alternate" type="text/html" title="记第一篇博客" /><published>2019-03-15T00:00:00+08:00</published><updated>2019-03-15T00:00:00+08:00</updated><id>https://iticfly.github.io/2019/03/15/gecko-embed</id><content type="html" xml:base="https://iticfly.github.io/2019/03/15/gecko-embed/">&lt;h3 id=&quot;记录我的第一篇博客&quot;&gt;记录我的第一篇博客&lt;/h3&gt;

&lt;p&gt;心血来潮，想着搭建个人技术博客。坚持下去，做技术的分享人，做自我的管理者。&lt;/p&gt;

&lt;p&gt;路漫漫兮其修远矣，吾将上下而求索。。。&lt;/p&gt;</content><author><name>Zhuang Ma</name></author><summary type="html">记录我的第一篇博客</summary></entry></feed>