线程

Servlet学习笔记

本秂侑毒 提交于 2020-03-11 06:32:31
一、Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的 数据库 或应用程序之间的中间层。 使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。 Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势: 1、性能明显更好。 2、Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。 3、Servlet 是独立于平台的,因为它们是用 Java 编写的。 4、服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。 5、Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。 二、Servlet的生命周期 Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程: 1、Servlet 通过调用 init () 方法进行初始化

Dubbo基本原理机制

被刻印的时光 ゝ 提交于 2020-03-11 05:26:57
分布式服务框架: –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 -Apache MINA 框架基于Reactor模型通信框架,基于tcp长连接 Dubbo缺省协议采用单一长连接和NIO异步通讯, 适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况 分析源代码,基本原理如下: client一个线程调用远程接口,生成一个唯一的ID(比如一段随机字符串,UUID等),Dubbo是使用AtomicLong从0开始累计数字的 将打包的方法调用信息(如调用的接口名称,方法名称,参数值列表等),和处理结果的回调对象callback,全部封装在一起,组成一个对象object 向专门存放调用信息的全局ConcurrentHashMap里面put(ID, object) 将ID和打包的方法调用信息封装成一对象connRequest,使用IoSession.write(connRequest)异步发送出去 当前线程再使用callback的get()方法试图获取远程返回的结果,在get()内部,则使用synchronized获取回调对象callback的锁, 再先检测是否已经获取到结果,如果没有,然后调用callback的wait()方法,释放callback上的锁,让当前线程处于等待状态。 服务端接收到请求并处理后,将结果(此结果中包含了前面的ID,即回传

alibaba远程调用框架dubbo原理

隐身守侯 提交于 2020-03-11 04:32:51
alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo、hsf),jms消息服务(napoli、notify),KV数据库(tair)等。这个框架/工具/产品在实现的时候,都考虑到了容灾,扩展,负载均衡,于是出现一个配置中心(ConfigServer)的东西来解决这些问题。 基本原理如图: 在我们的系统中,经常会有一些跨系统的调用,如在A系统中要调用B系统的一个服务,我们可能会使用RMI直接来进行,B系统发布一个RMI接口服务,然后A 系统就来通过RMI调用这个接口,为了解决容灾,扩展,负载均衡的问题,我们可能会想很多办法,alibaba的这个办法感觉不错。 本文只说dubbo,原理如下: ConfigServer 配置中心,和每个Server/Client之间会作一个实时的心跳检测(因为它们都是建立的Socket长连接),比如几秒钟检测一次。收集每个Server提供的服务的信息,每个Client的信息,整理出一个服务列表,如: serviceName serverAddressList clientAddressList UserService 192.168.0.1,192.168.0.2,192.168.0.3,192.168.0.4 172.16.0.1,172.16.0.2 ProductService 192.168.0.3

乐观锁与悲观锁、自旋锁

做~自己de王妃 提交于 2020-03-11 03:33:08
乐观锁 乐观锁是一种乐观的思想,即认为读多写少,遇到并发的可能性低, 每次拿数据时都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 ,可以使用版本号机制和 CAS 算法实现。 Java 中的乐观锁基本都是通过 CAS 操作实现的, CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 悲观锁 悲观锁就是悲观的思想,即认为写多,遇到并发的可能性高,每次拿数据时,都会认为别人会修改数据,所以在每次读数据的时候都会上锁,这样当别人想读写这个数据时就会阻塞,直到拿到锁。 (共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程) 。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。 Java 中的悲观锁就是 Synchronized,AQS 框架下的锁则是先尝试 CAS 乐观锁去获取锁,获取不到,才会转换为悲观锁,如 ReentrantLock。 乐观锁的缺点 ABA 问题 CAS 会导致 “ABA 问题”。CAS 算法实现的一个重要前提是需要取出内存中某时刻的数据,而在下一时刻比较并替换,那么在这个时间差会导致数据的变化。 比如说一个线程 one 从内存位置 V 中取出 A,这时候另一个线程 two 也从内存中取出 A,并且 two

弄懂 ThreadLocal,看这一篇就够了

独自空忆成欢 提交于 2020-03-11 03:07:27
1 什么是 ThreadLocal? ThreadLocal 类用于提供线程内部的局部变量,变量在多线程环境下访问(通过 get 和 set 方法访问)时能保证各个线程的变量相对独立于其他线程内的变量。ThreadLocal 实例通常来说都是 private static 类型的,用于关联线程和线程上下文。 ThreadLocal 有几个常用的方法,分别为 set(存储),get(获取),remove(删除),下面我会对这几个方法分别进行介绍。 2 set 方法 我们如何设置当前线程对应的值呢?通过 set 方法即可。 public void set ( T value ) { //获取当前线程 Thread t = Thread . currentThread ( ) ; //实际存储的数据结构类型 ThreadLocalMap map = getMap ( t ) ; //如果存在map就直接set,没有则创建map并set if ( map != null ) map . set ( this , value ) ; else createMap ( t , value ) ; } getMap 方法的实现如下: ThreadLocalMap getMap ( Thread t ) { //thred中维护了一个ThreadLocalMap return t .

JVM调优工具的使用方法

徘徊边缘 提交于 2020-03-11 02:39:05
常用的JVM调优工具:Jconsole,jProfile,VisualVMJconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用。对垃圾回收算法有很详细的跟踪。详细说明参考这里JProfiler:商业软件,需要付费。功能强大。详细说明参考这里VisualVM:JDK自带,功能强大,与JProfiler类似。推荐。 调优的方法观察内存释放情况、集合类检查、对象树上面这些调优工具都提供了强大的功能,但是总的来说一般分为以下几类功能 堆信息查看可查看堆空间大小分配(年轻代、年老代、持久代分配)提供即时的垃圾回收功能垃圾监控(长时间监控回收情况) 查看堆内类、对象信息查看:数量、类型等 对象引用情况查看 有了堆信息查看方面的功能,我们一般可以顺利解决以下问题: --年老代年轻代大小划分是否合理 --内存泄漏 --垃圾回收算法设置是否合理 线程监控线程信息监控:系统线程数量。线程状态监控:各个线程都处在什么样的状态下 Dump线程详细信息:查看线程内部运行情况死锁检查 热点分析 CPU热点:检查系统哪些方法占用的大量CPU时间 内存热点:检查哪些对象在系统中数量最大(一定时间内存活对象和销毁对象一起统计) 这两个东西对于系统优化很有帮助。我们可以根据找到的热点,有针对性的进行系统的瓶颈查找和优化,而不是漫无目的的进行所有代码的优化。快照

面试大厂一定离不开的——ThreadLocal,它的实现原理你知道吗?

你。 提交于 2020-03-11 00:13:20
使用场景 假设我们有一个数据库连接管理类: class ConnectionManager { private static Connection connect = null; private static String url = System.getProperty("URL"); public static Connection openConnection() { if(connect == null){ try { connect = DriverManager.getConnection(url); } catch (SQLException e) { e.printStackTrace(); } } return connect; } public static void closeConnection() { if(connect!=null) { try { connect.close(); } catch (SQLException e) { e.printStackTrace(); } } } } 如果这个类被用在多线程环境内,则会存在线程安全问题,那么可以对这两个方法添加synchronized关键字进行同步处理,不过这样会大大降低程序的性能,也可以将connection变成局部变量: class ConnectionManager { private

[RabbitMQ]基础概念——信道channel

折月煮酒 提交于 2020-03-10 20:41:32
目录 前言: 1.channel信道 1.1 为什么RabbitMQ 需要信道,如果直接进行TCP通信呢? 1.2 连接到RabbitMQ的示意图 前言: 最近跟着公司一起做项目重构,也有项目用到了MQ。其中用到了死信队列和延迟队列。 先整理一下路由的基础知识,不能只跟着实战,堆代码。 1.channel信道 信道是生产消费者与rabbit通信的渠道,生产者publish或者消费者消费一个队列都是需要通过信道来通信的。 信道是建立在TCP上面的虚拟链接,也就是rabbitMQ在一个TCP上面建立成百上千的信道来达到多个线程处理。 注意是一个TCP 被多个线程共享,每个线程对应一个信道,信道在rabbit都有唯一的ID,保证了信道的私有性,对应上唯一的线程使用。 1.1 为什么RabbitMQ 需要信道,如果直接进行TCP通信呢? 上述的描述其实已经很明显了,因为TCP可以被多个线程共享,显然线程比TCP要省事的多。 TCP的创建开销很大,创建需要三次握手,销毁需要四次握手。 如果不使用信道,那么引用程序就会使用TCP方式进行连接到RabbitMQ,因为MQ可能每秒会进行成千上万的链接, 总之就是TCP消耗资源 TCP链接可以容纳无限的信道,不会有并发上面的性能瓶颈。 在代码中并不会有直观的能看到信道这个概念。 因为代码中都是用自动配置。 @Autowired

操作系统-核心级线程

核能气质少年 提交于 2020-03-10 19:03:00
1. 和用户级相比,核心级线程有什么不同? 在用户级线程中,根据TCB(线程控制块)切换用户栈, 而核心级线程是,根据TCB(线程控制块)切换一套栈,切换用户栈和内核栈 2. 用户栈和内核栈之间的关联 进入内核栈的唯一方法是中断 例子: 3. 开始内核中的切换 switch_to 4. 内核线程switch_to的五段论 5. ThreadCreate 6. 用户级线程、核心级线程的对比 来源: https://www.cnblogs.com/mengd/p/12457798.html

你必须要知道的锁原理、锁优化、CAS、AQS

孤者浪人 提交于 2020-03-10 16:23:18
1、为什么要用锁? 锁-是为了解决并发操作引起的脏读、数据不一致的问题。 2、锁实现的基本原理 2.1、volatile Java编程语言允许线程访问共享变量, 为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁要更加方便。 volatile在多处理器开发中保证了共享变量的“ 可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。 结论:如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。 2.2、synchronized synchronized通过锁机制实现同步。 先来看下利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。 具体表现为以下3种形式。 对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁是当前类的Class对象。 对于同步方法块,锁是Synchonized括号里配置的对象。 当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。 2.2.1 synchronized实现原理 synchronized是基于Monitor来实现同步的。 Monitor从两个方面来支持线程之间的同步: 互斥执行 协作 1、Java