Netty

Java多线程中start()和run()的区别

五迷三道 提交于 2021-01-13 16:08:26
Java的线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法所定义的线程。可以通过创建Thread的实例来创建新的线程。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。 在Java当中,线程通常都有五种状态,创建、就绪、运行、阻塞和死亡: 第一是创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。 第二是就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。 第三是运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。 第四是阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个事件的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。 第五是死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。 实现并启动线程有两种方法: 1、写一个类继承自Thread类

Java多线程系列--“JUC集合”之 ArrayBlockingQueue

故事扮演 提交于 2021-01-13 15:36:55
ArrayBlockingQueue介绍 ArrayBlockingQueue是数组实现的线程安全的有界的阻塞队列。 线程安全是指,ArrayBlockingQueue内部通过“互斥锁”保护竞争资源,实现了多线程对竞争资源的互斥访问。而有界,则是指ArrayBlockingQueue对应的数组是有界限的。 阻塞队列,是指多线程访问竞争资源时,当竞争资源已被某线程获取时,其它要获取该资源的线程需要阻塞等待;而且,ArrayBlockingQueue是按 FIFO(先进先出)原则对元素进行排序,元素都是从尾部插入到队列,从头部开始返回。 注意: ArrayBlockingQueue 不同于 ConcurrentLinkedQueue , ArrayBlockingQueue 是数组实现的,并且是有界限的;而 ConcurrentLinkedQueue 是链表实现的,是无界限的。 ArrayBlockingQueue· 原理和数据结构 ArrayBlockingQueue 的数据结构,如下图所示: 说明: 1. ArrayBlockingQueue继承于AbstractQueue,并且它实现了BlockingQueue接口。 . ArrayBlockingQueue内部是通过Object[]数组保存数据的,也就是说ArrayBlockingQueue本质上是通过数组实现的

我是如何在短期内快速掌握Dubbo的原理和源码的(纯干货)?

拜拜、爱过 提交于 2021-01-13 12:24:19
写在前面 上周,在【Dubbo系列专题】中更新了两篇文章《 冰河开始对Dubbo下手了! 》和《 俯瞰Dubbo全局,阅读源码前必须掌握这些!! 》,收到了很多小伙伴的微信私聊消息,大部分都是在询问如何快速的掌握Dubbo的原理和源码。针对这个问题,我也在思考如何以更简单、易懂的方式让小伙伴们更好的掌握Dubbo的原理和源码。今天,我就为小伙伴们分享下我是如何快速掌握Dubbo的原理和源码的。 文章已收录到: https://github.com/sunshinelyz/technology-binghe https://gitee.com/binghe001/technology-binghe 阅读源码的前提 阅读某一项技术框架,或者说开源项目的源码前,你必须了解这个框架是干啥用的,说白了,就是你至少了解这个框架该怎么用,在什么场景下用,使用的过程中会遇到哪些坑,如何解决。而学习一个框架,最简单有效的方式就是它的官方文档。Dubbo也不例外,我在学习Dubbo的时候,也是首先看的Dubbo的官方文档,基本没看其他的文章或者资料。为啥?因为Dubbo的官方文档是最权威的,是最可信的。 即使你在项目中没有使用过Dubbo框架,你也可以按照Dubbo的官方文档基于Dubbo写一个简单的示例程序,通过示例能够让自己快速的了解Dubbo。 为何要阅读源码 阅读源码前

springboot 集成 vertx-kafka-client

白昼怎懂夜的黑 提交于 2021-01-13 11:02:24
为什么尝试做这个集成 vertx是一套封装了netty的异步事件驱动的框架,netty采用的线程模型可以高效处理某些情况下的网络通讯,然而这套框架需要程序员使用函数编程的方式,不是传统的方式。本项目主要是为了构建一个框架。熟悉springboot编程的程序员只需要通过注解或者接口编程的式就可以使用到 vertx-kafka-client。 项目依赖 集成demo采用的依赖如下,主要是spring-boot-starter-web和vertx-kafka-client。 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->

Java 浅析 Thread.join()

£可爱£侵袭症+ 提交于 2021-01-12 17:59:18
1. join() 的示例和作用 1.1 示例 1 // 父线程 2 public class Parent { 3 public static void main(String[] args) { 4 // 创建child对象,此时child表示的线程处于NEW状态 5 Child child = new Child(); 6 // child表示的线程转换为RUNNABLE状态 7 child.start(); 8 // 等待child线程运行完再继续运行 9 child.join(); 10 } 11 } 1 // 子线程 2 public class Child extends Thread { 3 public void run() { 4 // ... 5 } 6 } 上面代码展示了两个类:Parent(父线程类),Child(子线程类)。 Parent.main()方法是程序的入口,通过 Child child = new Child(); 新建child子线程(此时 child子线程处于NEW状态); 然后调用child.start()(child子线程状态转换为RUNNABLE); 再调用child.join(),此时,Parent父线程会等待child子线程运行完再继续运行。 下图是我总结的 Java 线程状态转换图: 1.2 join() 的作用

谈谈Java中的volatile

不打扰是莪最后的温柔 提交于 2021-01-12 16:51:28
内存可见性   volatile是Java提供的一种轻量级的同步机制,在并发编程中,它也扮演着比较重要的角色。同synchronized相比(synchronized通常称为重量级锁),volatile更轻量级,相比使用synchronized所带来的庞大开销,倘若能恰当的合理的使用volatile,自然是美事一桩。   为了能比较清晰彻底的理解volatile,我们一步一步来分析。首先来看看如下代码 public class TestVolatile { boolean status = false; /** * 状态切换为true */ public void changeStatus(){ status = true; } /** * 若状态为true,则running。 */ public void run(){ if(status){ System.out.println("running...."); } } }   上面这个例子,在多线程环境里,假设线程A执行changeStatus()方法后,线程B运行run()方法,可以保证输出"running....."吗?    答案是NO!   这个结论会让人有些疑惑,可以理解。因为倘若在单线程模型里,先运行changeStatus方法,再执行run方法,自然是可以正确输出"running...."的;但是在多线程模型中

用netty 实现http server

梦想与她 提交于 2021-01-12 01:47:25
workerGroup = new NioEventLoopGroup(); bossGroup = new NioEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup,workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG,100) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new HttpResponseEncoder()); socketChannel.pipeline().addLast(new HttpRequestDecoder()); socketChannel.pipeline().addLast(new HttpServerInboundHandler()); } })

netty server解决

半腔热情 提交于 2021-01-12 01:04:04
1、什么是粘包/拆包 ​ 一般所谓的TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢?主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的消息数据,所以就会引发一次接收的数据无法满足消息的需要,导致粘包的存在。处理粘包的唯一方法就是制定应用层的数据通讯协议,通过协议来规范现有接收的数据是否满足消息数据的需要。 2、解决办法 2.1、 消息定长 ,报文大小固定长度,不够空格补全,发送和接收方遵循相同的约定,这样即使粘包了通过接收方编程实现获取定长报文也能区分。 2.2、 包尾添加特殊分隔符 ,例如每条报文结束都添加回车换行符(例如FTP协议)或者指定特殊字符作为报文分隔符,接收方通过特殊分隔符切分报文区分。 2.3、 将消息分为消息头和消息体 ,消息头中包含表示信息的总长度(或者消息体长度)的字段 3、netty server端设置特殊分隔符 注意:分隔符一定要在数据处理的handler之前指定 @Component public class NettyServer { @Value("${netty.server.port}") private int port; /** * 启动 netty server * @throws InterruptedException */ public void start() {

心之所向,身之所往

浪尽此生 提交于 2021-01-11 01:41:13
欢迎关注我的微信公众号【 Mflyyou 】获取持续更新。 github.com/zhangpanqin/MFlyYou 收集技术文章及我的系列文章,欢迎 Star。 对于一个多月都没有双休的奋斗狗来说,明天能睡个懒觉真是太幸福了。 最近在赶项目进度,没时间更新博客,计划更新的内容(Mysql 系列,有时间再加更 JUC 相关)等到放假回家慢慢补吧。 ### 2020,再见 2020 年技术上算是有个不小的突破吧,我很满意,哈哈~ 看完《深入理解计算机系统》、《Linux 内核设计与实现》、《TCP/IP 详解 卷一》、《图解 TCP》、《图解 HTTP》五本书,再加上之前的《HTTP 权威指南》、算是打牢了自己的基础,对突破架构师有不小的助力。 深入研究了 redis 。看了一套收费教程和《Redis 深度历险》 Mysql 方面看了《Mysql 技术内幕 InnoDB 存储引擎》《Mysql 8 Cookbook》《Mysql 性能调优和高可用架构实践》,加上以前看的 《DBA 修炼之道》和 《高性能 Mysql》,Mysql 这块等系列博客写完,Mysql 这块我也算是过关了。 我始终认为会玩和玩的出神入化有着天壤之别。就像打农药,你上个王者还是轻轻松松的,但是上个国服还是挺有难度的。 因此对某项技术我都会花费很多的精力去研究,避免闭门造车,坐井观天。 2020 年开始写博客

专业性能Java描述符(修饰符)的类型

╄→尐↘猪︶ㄣ 提交于 2021-01-09 14:20:44
描述符(修饰符)是添加到那些定义中来改变他们的意思的关键词。Java语言有很多描述符,包括以下这些: 可访问描述符 不可访问描述符 应用描述符,可以在类、方法、变量中加入相应关键字。描述符要先于声明,如下面的例子所示: public class className { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { // body of method }//加入Java开发交流君样:756584822一起吹水聊天 一、可访问描述符 Java提供一系列可访问描述符来设定类,变量,方法和构造器的访问级别。四种访问级别如下: 默认的,对封装可见。不需要描述符。 仅对类可见(private) 全部可见(public) 对封装和子类可见(protected) 二、不可访问描述符 Java提供一些不可访问描述符来满足其他功能。 static描述符是用来创造类方法和变量的。 final描述符用来最终确定和实施类、方法和变量的。 abstract描述符用来创造不允许实例化的类和方法。