text: 资源利用率：在某些情况下，程序必须等待某个外部操作执行完成，例如输入操作或输出操作等，而在等待时程序无法执行其他任何工作。因此，如果在等待的同时可以运行另一个程序，那么无疑将提高资源的利用率。
  公平性：不同的用户和程序对于计算机上的资源有着同等的使用权。一种高效的运行方式是通过粗颗粒度的时间分片(TimeSlicing)使这些用户的程序能共享计算机资源，而不是由一个程序从头运行到尾，然后再启用下一个程序。
  便利性：通常来说，在计算多个任务时，应该编写多个程序，每个程序执行一个任务并在必要时互相通信，这比只编写一个程序来计算所有任务更容易实现。
  如果使用得当，线程可以有效地降低程序的开发和维护成本，同时提升复杂应用程序的性能。线程能够将大部分的异步工作流转换成串行工作流，因此能更好地模拟人类的工作方式和交互方式。此外，线程还可以降低代码的复杂度，使代码更容易编写、阅读和维护。
  过去，多处理器系统的非常昂贵和稀少的。但现在，多处理器系统日益普及，并且价格也不断地降低，即使在低端服务器和中端桌面系统，通常也会采用多个处理器。
  由于基本的调度单位是线程，因此如果在系统中只有一个线程，那么最多同时只能在一个处理器上运行。在双处理器系统上，单线程的程序只能使用一半的CPU次元，而在拥有100个处理器的系统上，将有99%的资源无法使用。另一方面，多线程程序可以同时在多个处理器上执行。如果设计正确，多线程程序可以通过提高处理器资源的利用率来提升系统的吞吐率。
  使用多个线程还有助于在单处理器系统上获得更高的吞吐率。如果程序是单线程的，那么当程序等待某个同步I/O操作完成时，处理器将处于空闲状态。而在多线程程序中，如果一个线程在等待I/O操作完成，另一个线程可以继续运行，使程序能够在I/O阻塞期间继续运行。
  通常，当只需要执行一种类型的任务时，在时间管理方面比执行多种类型的任务要简单。当只有一种类型的任务需要完成时，只需要埋头工作，知道完成所有任务，你不需要花任何经理来琢磨下一步该做什么。
  例如Servlet和RMI(RemoteMethodInvocation，远程方法调用)。框架负责解决一些细节问题，例如请求管理、线程创建、负载平衡，并在正确的时刻将请求分发给正确的应用程序组件。编写Servlet的开发人员不需要了解有多少请求在同一时刻被处理，也不需要了解套接字的输入流或者输出流是否被阻塞。当调用Servlet的servlet方法来响应Web请求时，可以以同步方式来处理这个请求，就好像它是一个单线程程序。这种方式可以简化组件的开发，并缩短掌握这种框架的学习时间。
  服务器应用程序接受来自多个远程客户端的套接字连接请求时，如果为每个链接都分配其各自的线程并使用同步I/O，那么就会降低这类程序的开发难度。
  如果某个应用程序对套接字执行读取操作而此时还没有数据到来，那么这个读取将一直阻塞，直到有数据到达。在单线程程序中，这不仅意味着在处理请求的过程中将停顿，而且还意味着在这个线程被阻塞期间，对所有请求的处理都将停顿。为了避免这个问题，单线程服务器应用程序必须使用非阻塞I/O，这种I/O的复杂性要远远高于同步I/O，并且很容易出错。然而，如果每个请求都拥有自己的处理线程，那么在处理某个请求时发生的阻塞将不会影响其他请求的处理。
  在现代GUI应用程序中，例如AWT和Swing等工具，都采用一个事件分发线程(EventDispatchThread,EDT)来代替主事件循环。当某个用户界面事件发生时，在事件线程中将调用应用程序的事件处理器。由于大多数GUI框架都是单线程子系统，因此到目前为止仍然在主事件循环，但它现在处理GUI工具的控制下并在其自己的线程中运行，而不是在应用程序的控制下。
  Java对线程的支持其实是一把双刃剑。虽然Java提供了相应的语言和库，以及一种明确的跨平台内存模型，这些工具简化了并发应用程序的开发，但同时也提高了对开发人员的技术要求，因为在更多的程序中会使用线程。
  线程安全性可能是非常复杂的，在没有充足同步的情况下，多个线程中操作执行顺序是不可预测的，甚至会产生奇怪的结果。
  在上面的代码中，UnsafeSequence类中将产生一个整数值序列，该序列中的每个值都是唯一的。在这个类中简要地说明了多个线程之间的交替操作将如何导致不可预料的结果。在单线程环境中，这个类能正确的工作，但在多线程环境中则不能。
  UnsafeSequence的问题在于，如果执行的时机不对，那么两个线程在调用getNext时会得到相同的值。虽然递增运算看上去是单个操作，但事实上它包含三个独立的操作：读取value，将value加1，并将计算结果写入value。由于运行时可能将多个线程之间的操作交替执行，因此这两个线程可能同时执行读取操作，从而使他们得到相同的值，并都将这个值加1。结果就是，在不同线程的调用中返回了相同的数值。
  UnsafeSequence类中说明的是一种常见的并发安全问题，成为竞态条件(RaceCondition)。在多线程环境下，getValue是否会返回唯一的值，要取决于运行时对线程中操作的交替执行方式，这并不是我们希望看到的。
  由于多个线程要共享相同的内存地址空间，并且是并发运行，因此它们可能会访问或修改其它线程正在使用的变量。当然，这是一种极大的便利，因为这种方式比较其他线程间的通信机制更容易实现数据共享。但它同样也带来了巨大的风险：线程会由于无法预料的数据变化而发生错误。当多个线程同时访问和修改相同的变量时，将会在串行编程模型中引入非串行因素，而这种非串行性是很难分析的。要使多线程程序的行为可预测，必须对共享变量的访问操作进行协同，这样才不会在线程之间发生彼此干扰。
  通过将getNext修改为一个同步方法，可以修改UnsafeSequence中的错误：
  如果没有同步，那么无论是编译器、硬件还是运行时，都可以随意安排操作的执行时间和顺序。虽然这些技术有助于实现更优秀的性能，并且通常也是值得采用的方法，但它们也为开发人员带来了负担，因为开发人员必须找出这些数据在哪些位置被多个线程共享，只有这样才能使这些优化措施不破坏线程安全性。
  在开发代码时，一定要注意线程安全性是不可破坏的。安全性不仅对于多线程程序很重要，对于单线程程序同样重要。此外，线程还会导致一些在单线程程序中不会出现的问题，例如活跃性问题。
  安全性的含义是“永远不发生糟糕的事情”，而活跃性则关注与另一个目标，即“某件正确的事情最终会发生”。当某个操作无法继续执行下去时，就会发生活跃性问题。在串行程序中，活跃性问题的形式之一就是无意中造成无限循环，从而使循环之后的代码无法得到执行。线程将带来一些其他的活跃性问题。包括死锁、饥饿、以及活锁。与大多数并发性错误一样，导致活跃性问题的错误同样是难以分析的，因为它们依赖于不同线程的事件发生时序，因此在开发或者测试中并不总是能够重现。
  与活跃性问题密切相关的是性能问题。活跃性意味着某件正确的事情最终会发生，但却不够好，因为我们通常希望正确的事情尽快发生。性能问题包括多个方面，例如服务时间过长，响应不灵敏，吞吐率过低，资源消耗过高，或者可伸缩性较低等。与安全性和活跃性一样，在多线程程序中不仅存在于单线程程序相同的性能问题，而且还存在由于使用线程而引入的其他性能问题。
  在设计良好的并发应用程序中，线程能提升程序的性能，但无论如何，线程总会带来某种程度的运行时开销。在多线程程序中，当线程调度器挂起活跃线程并转而运行另外一个线程时，就会频繁的出现上下文切换操作(ContextSwitch)，这种操作将带来极大的开销：保存和恢复执行上下文，丢失局部性，并且CPU时间将更多地花在线程调度而不是运行上。当线程共享数据时，必须使用同步机制，而这些机制往往会抑制某些编译器优化，使内存缓存区中的数据无效，以及增加共享内存的总线的同步流量。所有这些因素都将带来额外的性能开销。
  每个Java应用程序都会使用线程。当JVM启动时，它将为JVM的内部任务创建后台线程，并创建一个主线程来运行main方法。AWT和Swing的用户界面框架将创建线程来管理用户界面事件。Timer将创建线程来执行延迟任务。一些组件框架，例如Servlet和RMI，都会创建线程池并调用这些线程中的方法。
  如果要使用这些功能。那么就必须熟悉并发性和线程安全性，因为这些框架将创建线程并且在这些线程中调用程序中的代码。虽然将并发性认为是一种“可选的”或者“高级的”语言功能固然理想，但现实的情况是，几乎所有的Java应用程序都是多线程的，因此在使用这些框架时仍然需要对应用程序状态的访问进行协同。
  当某个框架在应用程序中引入并发性时，通常不可能将并发性仅局限于框架代码，因为框架本身会回调(Callback)应用程序的代码，而这些代码将访问应用程序的状态。同样，对线程安全性的需求也不能局限于被调用的代码，而是要延伸到需要访问这些代码所访问的程序状态的所有代码路径。因此，对线程安全性的需求将在程序中蔓延开来。
  框架通过在框架线程中调用应用程序代码将并发性引入到程序中。在代码中将不可避免地访问应用程序状态，因此所有访问这些状态的代码路径都必须是线程安全的。
  编程语言一直是学习计算机编程门专业的热门讨论话题，而我也选择了这个专业，入学一年了，马上面临着语言的选择问题，业余我需要选择一门编程语言作为重点研究对象，那么问题来了：到底是选择
  前言目前计算句子相似性有很多不同的方案，比如基于语义词典的方法、基于相同词汇的方法、基于统计的方法和基于编辑距离的方法。这篇文章先介绍编辑距离的基础。编辑距离编辑距离其实就是
  一名Java开发工程师不仅要对Java语言及特性有深层次的理解而且需要掌握与Java相关的框架、生态及后端开发知识本文涉及多种后端开发需要掌握的技能对于帮助提高开发能力非常有帮助NO.1
  前言据我所知Java开发人员几乎任何时候都会想到String，字符串确实已经成为最常用的类了，而且是大量使用。我们都知道，String其实是封装了字符，里面必须由字符或字节数组来存放，从
  前言目前做分词比较流行的是用深度学习来做，比如用循环神经网络和条件随机场，也有直接用条件随机场或隐马尔科夫模型的。前面也实现过上面几种，效果挺不错，基于隐马尔科夫模型的差一点，
  前言对于chatbot，现在学界更流行的实现方式是基于深度学习和强化学习，比如seq2seq模型，具体可参考前面的文章《深度学习的seq2seq模型》。而对于工业界，直接用seq2seq模型来实现端对
  一、前言在同一个jvm进程中时，可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题，但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候，juc包的锁就
  DavidJohnWheeler有一句名言“计算机科学中的任何问题都可以通过加上一层间接层来解决”，一层不够就再加一层。后半句是我加的(*￣︶￣)，虽然有点玩笑的意思，但是也的确能说明一些问题
  全球最大的开发者社区GitHub网站花落谁家的问题已经敲定，微软最终以75亿美元迎娶了这位在外界看来无比“神秘”的小家碧玉。尽管此事已过去一些时日，但整个开发者世界，包括全球各地的开源社
  前言经过前期所有的准备工作，Spring已经获取到需要创建实例的beanName和对应创建所需要信息BeanDefinition，接下来就是实例创建的过程，由于该过程涉及到大量源码，所以将分为多个章节进
  1、可视化排序过程对{6,5,3,1,8,7,2,4}进行冒泡排序的可视化动态过程如下2、代码实现publicvoidcontextLoads(){//冒泡排序int[]a={6,5,3,1,8,7,2,
  1.首先在pom文件的plugins中添加maven对mybatis-generator插件的支持`<!--mybatis逆向工程--><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-ma