05单件模式

经典的单件模式

public class Singleton {
  private static Singleton uniqueInstance; //一个静态变量持有Singleton类的唯一实例。
  // 其他有用的实例变量写在这里

  //构造器声明为私有,只有Singleton可以实例化这个类!
  private Singleton() ()
  
  public static Singleton getInstance(){
    if(uniqueInstance == null){
        uniqueInstance = new Singleton();//getInstance()方法提供了一种实例化该类的方式,也返回它的一个实例。
    }
    return uniqueInstance ;
  }
}

单件模式没有公开的构造器,构造器声明为私有;为了获得一个单件对象,不是实例化一个,只是请求一个实例。因此类有一个静态方法,称为getInstance()。

用途:常常被用来管理资源池,像连接或者线程池。

你有一个包含注册表设置的对象。你不想让这个对象有多个副本,到处赋值一这会导致混乱。通过使用像单件模式这样的对象,你可以确保应用中的每个对象使用同一全局资源。

例子--巧克力工厂

一个Choc-O-Hoic公司的工业强度巧克力锅炉控制器类

public class ChocolateBoiler {
  private boolean empty;
  private boolean boiled;

  //这段代码只有在锅炉空的时候才启动!
  public ChocolateBoiler(){
    empty = true;
    boiled = false;
  }

  //要往锅炉里填充原料,锅炉必须是空的。一旦锅炉满了,我们就设置empty和boiled标志
  public void fill() {
    if(isEmpty()) {
        empty = false;
        boiled = false;
        //往锅炉里填充牛奶/巧克力混合物
    }
  }

  //要排空锅炉,锅炉必须是满的 (非空) 且煮过的。一旦排出完毕,我们把empty设置回true。
  public void drain() {
    if(!isEmpty() && isBoiled()) {
        //排出煮沸的牛奶和巧克力
        empty = true;
    }
  }

  //要煮混合物,锅炉必须是满而且未煮过的。一旦煮沸,我们r把boiled标志设为true。
  public void boil() {
    if(!isEmpty() &&!isBoiled()) {
        //将炉内物煮沸
        boiled = true;
    }
  }

  public boolean isEmpty() {return empty;}
  public boolean isBoiled() (return boiled;}
}

改成单件模式

public class ChocolateBoiler {
  private boolean empty;
  private boolean boiled;

  //改动一:
  private static Chocolateboiler uniqueinatance;

  //改动二:
  private ChocolateBoiler(){
    empty = true;
    boiled = false;
  }
  //改动三:
  public static ChocolateBoiler getInstance(){
    if(uniqueInstance == null) {
      uniqueInstance = new ChocolateBoiler()
    }
    return uniqueInstance;
  }

  public void fill() {
    if(isEmpty()) {
      empty = false;
      boiled = false;
      //往锅炉里填充牛奶/巧克力混合物
    }
  }
  // 剩下的chocolateBoiler代码·
}

单件模式

单件模式:确保一个类只有一个实例,并提供一个全局访问点;
类图:

添加线程造成的问题

解决多线程:通过把getInstance()方法变成同步(Synchronized)方法;
但是同步导致性能开销大

改进多线程

1.如果getlnstance()的性能对应用来说不是很关键,什么也不做。
2.转为急切(eagerly) 创建实例,而不用延迟创建

用这个方法,当类被加载时,我们依靠JVM来创建单件的唯一实例。JVM 保证在任何线程访问静态uniqueInstance变量之前,实例会被创建。

public class Singleton {
  //在静态初始化器中创建单件实例,这段代码保证是线程安全的!
  private static Singleton uniqueInstance = new Singleton();
  private Singleton() {}

  public static Singleton getInstance() {
    return uniqueInstance;//我们已经有了一个实例,因此返回它即可。
  }
}

3.用“双重检查加锁”在getlnstance()减少使用同步
双重检查加锁不适用1.4以及更早版本的Java!

public class Singleton {
  //volatile关键词确保:当uniquelnstance变量被初始化为单件实例时,多个线程正确处理uniquelnstance变量
  private volatilestatic Singleton uniqueInstance;
  private Singleton() {}
  
  public static Singleton getInstance() {
    if(uniqueInstance == null) {//检查实例,如果没有,进入同步区块。
       synchronized(Singleton.class){//注意,只有第一次才同步
          if(uniqueInstance == null) {
              uniqueInstance = new Singleton();//进入区块后,再检查一次。如果依然是空的,创建一个实例。
          }
        }
    }
    return uniqueInstance;
  }
}

总结

单件,确保一个类只有一个实例,并提供全局访问点。
当你需要确保应用中的某个类只有一个实例,就用单件模式吧。

要点

1.单件模式确保应用中个类最多只有一个实例。
2.单件模式也提供访问此实例的全局点。
3.Java的单件实现用了一个私有构造器、一个静态方法以及一个静态变量。
4.检查你的性能和资源约束,为多线程应用小心选择一个适当的单件实现 (我们应该把所有应用都考虑为是多线程的)。
5.提防双重检查加锁实现。Java 5之前的版本,不是线程安全的
6.如果你使用多个类加载器,要小心,可能导致单件实现失效,导致出现多个实例。
7.你可以使用Java的枚举来简化单件的实现。

本文转载于网络 如有侵权请联系删除

相关文章

  • Laravel Exceptions——异常与错误处理

    复制前言 本文GitBook地址:https://legacy.gitbook.com/book/leoyang90/laravel-source-analysis/details对于一个优秀的框架来说,正确的异常处理可以防止暴露自身接口给用户,可以提供快速追溯问题的提示给开发人员。本文会详细的介绍laravel异常处理的源码。PHP异常处理本章节参考PHP错误异常处理详解。异常处理(又称为错误处理)功能提供了处理程序运行时出现的错误或异常情况的方法。异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。当异常被触发时,通常会发生:当前代码状态被保存代码执行被切换到预定义的异常处理器函数根据情况,处理器也许会从保存的代码状态重新开始执行代码,终止脚本执行,或从代码中另外的位置继续执行脚本PHP5提供了一种新的面向对象的错误处理方法。可以使用检测(try)、抛出(throw)和捕获(catch)异常。即使用try检测有没有抛出(throw)异常,若有异常抛出(throw),使用catc

  • ATMMalScan - DFIR搜索ATM上的恶意软件痕迹。

    ATMMalScan是Windows7和更高版本的Windows操作系统的命令行工具,有助于在DFIR流程中在ATM上搜索恶意软件跟踪。该工具根据指定的文件路径检查系统以及硬盘的运行过程。要扫描系统,具有标准权限的用户就足够了。但是,ATMMalScan具有管理员权限,可以提供最佳结果。已知的问题: 当前,ATMMalScan不支持需要Unicode的代码页,这意味着Windows操作系统设置为例如西里尔字母或中文字符,无法保证代表性的结果。 要求: 确保至少要扫描的ATM上已经安装了VisualStudio2015的VisualC++Redistributable。 用法(示例) 步骤1=>扫描进程内存和磁盘。===>检查设备上是否具有管理员权限以获得最佳结Step2=>ATMMalScan在进程中检测到一个名为XFS_DIRECT的恶意软件,提供有关线程及其规则匹配的详细信息。此外,完整的进程内存转储已保存到磁盘,以捕获恶意进程,其模块以及其堆栈和堆页面。 Step3=>转储可以在这里找到=>.\DumpStep4=>使用Windbg打开转储文件

  • 单调递增的数字

    单调递增的数字给定一个非负整数N,找出小于或等于N的最大的整数,同时这个整数需要满足其各个位数上的数字是单调递增。当且仅当每个相邻位数上的数字x和y满足x<=y时,我们称这个整数是单调递增的。示例输入:N=10 输出:9复制输入:N=1234 输出:1234复制输入:N=332 输出:299复制题解/** *@param{number}N *@return{number} */ varmonotoneIncreasingDigits=function(N){ leti=1; letnum=N; while(i*10<=num){ //console.log(i,num); //每次取出两位 letn=~~(num/i)%100; i=i*10; if(~~(n/10)>n%10)num=~~(num/i)*i-1; //例如1332第一次循环之后是取整(1332/10)*10-1=1330-1=1329 //第二次循环就是1300-1=1299 } returnnum; };复制思路整体思路就是将数字当作字符串,从尾到头逆向遍历一遍,每次比较两位,如果后一个位置上的数

  • windows常用进程

    一、最基本的系统进程也就是说,这些进程是系统运行的基本条件,有了这些进程,系统就能正常运行1、smss.exeSessionManager2、csrss.exe子系统服务器进程3、winlogon.exe管理用户登录4、services.exe包含很多系统服务5、lsass.exe管理IP安全策略以及启动ISAKMP/Oakley(IKE)和IP安全驱动程序。(系统服务)产生会话密钥以及授予用于交互式客户/服务器验证的服务凭据6、ticket。(系统服务)->netlogon7、svchost.exe包含很多系统服务!!!->eventsystem8、SPOOLSV.EXE将文件加载到内存中以便迟后打印(没有打印机也不必了)。9、explorer.exe资源管理器10、internat.exe托盘区的拼音图标,装了OfficeXP及以上者为ctfmon.exe。二、附加的系统进程这些进程不是必要的,你可以根据需要通过服务管理器来增加或减少1、mstask.exe允许程序在指定时间运行。(系统服务)->schedule2、regsvc.exe允许远程注册表操作。(系统服

  • 如何进行直播带货APP开发

    接触过电商的朋友可能听说过“直播带货”这个词,单从字面意思上来讲,它似乎代表一种新兴的销售行为。但是,这种销售行为毕竟是要依托于直播或者短视频等线上平台的支持。于是有一部分眼光独到的软件开发商对直播软件进行了升级,进行直播带货APP开发。那么,开发的核心步骤是什么呢?在线商城一、确定商城的模式直播带货APP开发的核心是要突出“店铺+商城”两个元素,店铺不用多说,肯定是要内嵌在直播软件中的,关键就是对这个“商城”的处理了。针对于它的开发,主要分为两个方向:第一种,直接把相关商品的链接关联到自己的第三方商城中,例如淘宝或天猫商城,这样的话,虽然开发的成本降低了,但是作为用户的店长来说,就要随时修改和同步两方的商品信息了,很不方便。第二种:使用自行开发的商城系统。由于商铺和商城是使用同一个管理后台,因此往往只需要在商铺中输入商品ID,便可以自动绑定其商品信息,而且后续一旦对直播商铺进行升级,就不会担心因为和商城不兼容而造成的诸多麻烦,毕竟是出自同一个开发团队,这种问题还是能一并解决的。直播带货二、明确商城的功能如果软件商决定自行开发商城,那么可要对其中所涉及到的功能进行深入探究了。一个完整的

  • Kustomize 和 Helm 之间,我为什么选择了 Kustomize?

    本文将记录为什么最终没有采用Helm而是选择了Kustomize作为Kubernetes应用的部署工具。使用各种项目管理之前的情况首先说说之前的痛点。我们虽然不是个大公司,可是这代码也是越敲越多,服务也是越做越全。零零总总也有十几个项目要管理了。然后我们同样有多套部署环境:内网环境,预生产环境,生产环境。那么针对每一个环境几乎都要有一套Kubernetes的YAML文件,但是各个仅仅是稍有不同。然后我们自己的CI是将构建好的Docker镜像放到Registry里面。那么,每次更新的镜像之后就是通过人手工去部署一下,绝大多数情况就是修改一下镜像的Tag,但是由于每个环境的YAML略有区别,那么如果我需要在不同环境切换的时候就需要来回修改这些YAML文件,一不小心写错了就只能怪自己手残。然而这种部署方式虽然在Kubernetes之下就是改改YAML就好了,但是依然感觉很是原始。希望有什么改善仔细想想,自己的需求就是这么几个:有一个统一的模板可以管理一个项目的Kubernetes部署结构。 有某种方式可以管理不同环境之间微小的差异。 每次更新基本就是修改镜像的标签然后部署,那么有没有什么

  • Web基础配置篇(五): Nginx的配置及代理转发

    Web基础配置篇(五):Nginx的配置及代理转发一、概述Nginx(enginex)是一个高性能的HTTP和反向代理web服务器。说到web服务器,你可以疑惑,前面说的tomcat不也是web服务器么,为啥要用nginx?这里要说明一下:nginx是一个轻量级高并发服务器,而tomcat并不是。nginx一般被用来做反向代理,将请求转发到应用服务器上,比如tomcat的应用。nginx可以配置负载均衡。nginx一般也用来处理跨域,或者用来将前后端分离情况下的前后端同域。nginx做服务器,可以做静态资源处理,也可以进行复杂业务处理,比如OpenResty,是一个基于Nginx与Lua的高性能Web平台。**如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以<ahref="https://jq.qq.com/?_wv=1027&k=52sgH1J"target="_blank">加入我们的java学习圈,点击即可加入</a>,共同学习,节约学习时间,减少很多在学习中遇到的难题。**二、Nginx安

  • 快速排序 c/c++

     选择基准数(为方便选取第一个元素),定义两个指针i,ji从头开始扫,j从尾开始扫使得基准数左边的元素小于基准数,基准数右边的元素大于基准数由于基准数选取的是第一个元素,j先动,找到小于基准数的值,i再动,找到大于基准数的值,交换i和j的值直到i和j相遇,则把相遇位置的值和基准数的值交换这时把数组看作只有三个元素,小于基准数,基准数,大于基准数,此时是有序的按照这种思想,递归处理小于基准数和大于基准数两部分#include<bits/stdc++.h> usingnamespacestd; voidquick_sort(int*arr,intleft,intright) { if(left>right) return; inti=left; intj=right; intat=*(arr+left); while(i!=j) { while(*(arr+j)>=at&&i<j) j--; while(*(arr+i)<at&&i<j) i++; inttp

  • ES5新增

    forEach//forEach返回undefined vararr=['Prosper','Lee','is',['very','very'],'nice','!',,null]; //ES6写法 arr.forEach((currentValue,index,array)=>{ console.log('arr['+index+']='+array[index]+'=='+currentValue); console.log(array.join(",").split(",").join('')); }); arr.forEach(function(currentValue,index,array){ console.log('arr['+index+']='+array[inde

  • 布局库新版本发布2018-09-21

    本次版本更新主要为了更好的支持新上市的iPhoneX系列设备和BUG修复。OC版本和Swift版本都于2018年09月21号同步更新,并更新到cocoapods中:OC版本:MyLayout1.6.1修复了在所有iPhoneX系列设备上的布局视图的padding值设置为MyLayoutPos.safeAreaMargin时的问题。老版本中这部分代码是硬编码为只支持iPhoneX设备,这次更新解决了对所有iPhoneX系列设备的支持。修复了#issue81中的问题描述,布局库可以用于对ApplicationExtension的开发和支持。老版本中代码用到了UIApplication对象,但是Extension中是没有这个对象的,所以编译报错,新版本中对这个问题进行了修复。Swift版本:TangramKit1.3.0重点是实现了对Swift4.2的兼容和支持。将老版本中的一些编译告警进行修复和处理以便支持最新的Swift版本。参见:#issue26,#issue21修复了浮动布局TGFloatLayout中的子视图的尺寸TGLayoutSize设置为TGWeight类型时可能会计算不正确

  • 论文 | 预测 API 从谷歌、亚马逊等大平台盗取机器学习算法

    2016年10月18日,世界人工智能大会技术分论坛,特设“新智元智库院长圆桌会议”,重量级研究院院长7剑下天山,汇集了中国人工智能产学研三界最豪华院长阵容:美团技术学院院长刘江担任主持人,微软亚洲研究院常务副院长芮勇、360人工智能研究院院长颜水成、北京理工大学计算机学院副院长黄华、联想集团副总裁黄莹、Intel中国研究院院长宋继强、新华网融媒体未来研究院院长杨溟联袂出席。【新智元导读】CornellTech研究人员发现,使用预测API通过反向工程,能够从谷歌、亚马逊等大平台“偷”机器学习算法,准确率超过99%。不仅如此,偷完算法后,还可以强制它生成训练用的数据样本。这意味着不仅能够从谷歌、微软偷走人工智能产品并且免费使用它们,大公司独有的数据也面临威胁。无数金钱被投入去设计精密的人工智能算法,但只要有一扇小小的门开着,这些算法就可能被偷走。AI算法和源数据能被轻而易举地偷取现在,有一项研究发现,只需使用API就能通过反向工程得到机器学习算法,准确率超过99%。这意味着能够从微软、IBM这些公司偷走人工智能产品,免费使用它们。只有单一机器学习API的小公司可能会失去全部竞争优势。而且,

  • Redis实现分布式锁

    之前写过一篇博客,里面吭哧吭哧半天,使用Redis实现了一个分布式锁。今天闲来没事看源码,突然发现redisset命令的用法可以直接指定nx和ex,文档中没有明说这是个原子方法,但是后面给出了一个例子使用setnxex的方法实现了redis锁。感觉应该是原子性的,挺好。相比这篇文章里的方法,有两个优点:1)简单,之前的那篇文章里使用getSet方法,折腾了一顿,就是怕setnx之后expire成功不了,这里直接原子性的话,省事多了。2)解决了超时误删锁引入的竞态问题,之前我们在value中保留了时间,这里我们可以保留一个uuid,判断是自己的锁再删除,避免误删。直接粘在下面,以后实现了实例再回来。api出处:http://doc.redisfans.com/string/set.html命令 SET resource-name anystring NX EX max-lock-time 是一种在Redis中实现锁的简单方法。客户端执行以上的命令:如果服务器返回 OK ,那么这个客户端获得锁。如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。设置的过期时间到达之后,锁将自

  • 数据结构之归并排序

    什么是归并排序归并排序是一种采用了分治法的高速排序算法,它通过不断递归自身,将要被排序的数列分成两部分进行排序。再将已排序的两部分数列合并起来即可。整个算法的关键在与合并两个数列的函数,它必须是一个时间复杂度为O(n1+n2)的函数。归并排序由分割数列的函数和组合数列的函数组成,整体时间复杂度为O(nlogN),这相比于前面的O(N²)的初等排序算法来说,提速是很明显的。并且,归并排序是稳定排序算法。在合并数组的时候,只要保证前一个数列的优先级高于后一个数列,那么相同元素的顺序就不会颠倒。所以它是一个稳定排序。算法实现归并排序实质就是把一个数列分割成两个,再把每个子列再分割,直到无法再分为止,然后用一个函数来把排序好的子列组装起来。这就是递归与分治问题的一种。为了简化merge函数的实现,我们在前一个列和后一个列的末位添加一个很大很大的数,那么就能防止计数器越过n1、n2,并且能防止两个标记元素互相比较。啊感觉有点复杂,还是赶紧上代码吧,这样或许能帮助理解。问题问题出自:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=A

  • TCPClient、TCPListener的用法

    TCPClient、TCPListener的用法     支持Http、Tcp和Udp的类组成了TCP/IP三层模型(请求响应层、应用协议层、传输层)的中间层-应用协议层,该层的类比位于最底层的Socket类提供了更高层次的抽象,它们封装TCP和UDP套接字的创建,不需要处理连接的细节,这使得我们在编写套接字级别的协议时,可以更多地尝试使用TCPClient、UDPClient和TcpListener,而不是直接向Socket中写。   可见,TcpClient类基于Socket类构建,这是它能够以更高的抽象程度提供TCP服务的基础。正因为这样,许多应用程上的通讯协议,比如FTP(FileTransfersProtocol)文件传输协议、HTTP超文本传输协议等都直接创建在TcpClient等类之上。   TCPClient类使用TCP从Internet资源请求数据。TCP协议建立与远程终结点的连接,然后使用此连接发送和接收数据包。TCP负责确保将数据包发送到终结点并在数据包到达时以正确的顺序对其进行组合。    从名字上就可以看出,TcpClient类专为客户

  • Vmware 虚拟机Ubuntu系统,解决忘记用户名和密码解决办法

    1、在开机界面按住shift,会加载grub的启动界面,找到AdvacedoptionsforUbuntu选项。按"e"进入编辑模式。 2、光标移动至ro,改为rw,(Linux系统中的文件属性标识方法,改成rw后才能对系统文件进行修改。)按F10保存。 3、进入AdvacedoptionsforUbuntu,会发现选项后面带有recoverymode。回车进入。 4、移动选项至root,点击[ok]或者回车进入命令行。  5、PressEnterformaintenance,出现该文本,按下Enter键,工具查看cat/etc/passwd文件,找到用户名,然后使用命令sudopasswdusername来修改username的密码。 或者使用useradd命令来添加一个新用户,注意要使用passwdnewuser后才能使用newuser登录。此时就可以输入指令修改密码了。  6、reboot重启,即可进入登录界面,正常登录。  

  • Hadoop的Server及其线程模型分析

    早期的一篇文章,针对Hadoop2.6.0. 一、Listener## Listener线程,当Server处于运行状态时,其负责监听来自客户端的连接,并使用Select模式处理Accept事件。 同时,它开启了一个空闲连接(IdleConnection)处理例程,如果有过期的空闲连接,就关闭。这个例程通过一个计时器来实现。 当select操作调用时,它可能会阻塞,这给了其它线程执行的机会。当有accept事件发生,它就会被唤醒以处理全部的事件,处理事件是进行一个doAccept的调用。 doAccept: voiddoAccept(SelectionKeykey)throwsInterruptedException,IOException,OutOfMemoryError{ ServerSocketChannelserver=(ServerSocketChannel)key.channel(); SocketChannelchannel; while((channel=server.accept())!=null){ channel.configureBlocking(fals

  • 注入DLL之主线程方式

    目前对于APC注入方式依然还没有了解内幕, QueueUserAPC((PAPCFUNC)LoadLibraryA,hThread,(ULONG_PTR)param); 但看其调用方式可以猜出一二。,基本也是插入到线程再装载DLL。 以前在黑客防线里看到过主线程注入方式装载DLL,研究了一下,发现很像是手工实现了QueueUserApc的功能。。。不过这种比直接调用API更自由灵活。 另不知怎么回事,WIN7下与黑客防线所载文章实例中的细节有些出入。 首先黑客防线里的找主线程的方式有些绕,他比较了线程时间,我也没细看,观察了一阵,发现一般第一个线程就是主线程,姑且就这么着吧   分析一下:【主要用于备忘,别人能不能看懂我就不知道了】 一,读取线程的等待状态下的数据,线程一般分等待与激活状态,如果没有任务就会处于等待状态,当有操作就会处于激活状态。 二,写注入代码到注入进程     1,保存并改写线程RET时的ESP值,里面放的是调用该函数处存放的下一条指令地址。。。指向注入代码    &nbs

  • 常见分布式存储系统架构分析

    ceph,tikv,小米飞马,GFS,etcd 存储系统分片后,如果不均衡,某一片写满了一台服务器,其他服务器还很空怎么处理的呢 ceph Ceph数据复制算法和Raft数据一致性算法对比分析 ceph体系结构 分布式存储Ceph介绍及原理架构分享下 cephhandlestalereadwithreadlease infoqceph系列 ceph架构 ceph存储集群包括osd、monitor和client三个组件 osd提供单机存储与数据复制 monitor负责保存集群元数据,包括osdmap(包括osd状态等),crushmap(包括物理层次结构及访问规则),pgmap等,monitor本身也是一个paxos强一致性集群 client是请求接入的地方,会去monitor请求osdmap,crushmap,crushrules,然后根据objid->pgid->osdsets crush算法 ceph说自己没有leader,根据crush算法来算的,算到谁就是谁,那算出来的leader挂掉的呢,是需要向monitor拿视图吗? CRUSH算法是一个伪随机的过程

  • 查看交叉编译器版本显示为找到的解决

    一般编译器是32位的,在64位的系统上面查看版本是显示无法找到的。 解决方法:安装32位的库 sudoapt-getinstalllib32ncurses5lib32z1  

  • 三载忘忧

    作曲:钦觉 演唱:钦觉 作词:萧兮凉子 编曲:乐正弦 念白:钦觉、了尘、江懿黎 海报:以渡 制作:剑侠情缘手游 江:我看过很多地方的桃花,走过很多地方的桥,喝过很多地方的酒, 却没在任何一处停留过。 歌词: 千家灯火,天地脉脉,滔滔多少过客。 山河落落,尘世漂泊,仗剑赴风波。 风烟俱落,江天漠漠,辽阔天地和我。 恍然失落,一梦如昨,往事最难割舍。 钦:你眼中是这江湖,我眼中是你。 歌词: 人生行止,江湖恣意,快马驰千里。 枪尖如霓,寒芒飞起,胜败输赢不计。 只愿与你,一见倾心,江湖相守相依。 世间离散,只要一句,白首莫相离。 了:江湖同载酒,有你才忘忧。 歌词: 扇出游龙,剑舞惊鸿,负手恩怨重重。 衣袂如虹,风虎云龙,朗朗乾坤翻涌。 歌词: 人生行止,江湖恣意,快马驰千里。 枪尖如霓,寒芒飞起,胜败输赢不计。 只愿与你,一见倾心,江湖相守相依。 世间离散,只要一句,白首莫相离。 歌词: 人生行止,江湖恣意,快马驰千里。 枪尖如霓,寒芒飞起,胜败输赢不计。 只愿与你,一见倾心,江湖相守相依。 世间离散,只要一句,白首莫相离。 了、钦:剑心未老情缘未了三生有幸江湖有你 钦

  • 文本的向量化表达

                             

相关推荐

推荐阅读