以DefaultFuture为例,看类变量初始化顺序
https://stackoverflow.com/questions/8517121/java-what-is-the-difference-between-init-and-clinit#
<init> is the (or one of the) constructor(s) for the instance, and non-static field initialization.
<clinit> are the static initialization blocks for the class, and static field initialization.
以DefaultFuture为例,分析java类中各变量的初始化顺序。
首次执行代码:DefaultFuture future = new DefaultFuture(channel, req, timeout);
1. 首先加载class文件(Launcher$AppClassLoader(ClassLoader).loadClass(String) line: 358)
2. 进DefaultFuture.<clinit>(),顺序执行static语句
为static变量赋值
private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class);
private static final Map<Long, Channel> CHANNELS = new ConcurrentHashMap<Long, Channel>();
private static final Map<Long, DefaultFuture> FUTURES = new ConcurrentHashMap<Long, DefaultFuture>();
执行后面的static语句
static {
Thread th = new Thread(new RemotingInvocationTimeoutScan(), "DubboResponseTimeoutScanTimer");
th.setDaemon(true);
th.start();
}
3. 进构造函数(DefaultFuture.<init>(Channel, Request, int) line: 73)
4. 执行实例变量赋值语句(构造函数外部的赋值语句先执行)
private final Lock lock = new ReentrantLock();
private final Condition done = lock.newCondition();
private final long start = System.currentTimeMillis();
5. 执行构造函数
public DefaultFuture(Channel channel, Request request, int timeout){
this.channel = channel;
this.request = request;
this.id = request.getId();
this.timeout = timeout > 0 ? timeout : channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
// put into waiting map.
FUTURES.put(id, this);
CHANNELS.put(id, channel);
}
DefaultFuture源码如下:
- package com.alibaba.dubbo.remoting.exchange.support;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.TimeUnit;
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- import com.alibaba.dubbo.common.Constants;
- import com.alibaba.dubbo.common.logger.Logger;
- import com.alibaba.dubbo.common.logger.LoggerFactory;
- import com.alibaba.dubbo.remoting.Channel;
- import com.alibaba.dubbo.remoting.RemotingException;
- import com.alibaba.dubbo.remoting.TimeoutException;
- import com.alibaba.dubbo.remoting.exchange.Request;
- import com.alibaba.dubbo.remoting.exchange.Response;
- import com.alibaba.dubbo.remoting.exchange.ResponseCallback;
- import com.alibaba.dubbo.remoting.exchange.ResponseFuture;
- /**
- * DefaultFuture.
- *
- * @author qian.lei
- * @author chao.liuc
- */
- public class DefaultFuture implements ResponseFuture {
- private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class);
- private static final Map<Long, Channel> CHANNELS = new ConcurrentHashMap<Long, Channel>();
- private static final Map<Long, DefaultFuture> FUTURES = new ConcurrentHashMap<Long, DefaultFuture>();
- // invoke id.
- private final long id;
- private final Channel channel;
- private final Request request;
- private final int timeout;
- private final Lock lock = new ReentrantLock();
- private final Condition done = lock.newCondition();
- private final long start = System.currentTimeMillis();
- private volatile long sent;
- private volatile Response response;
- private volatile ResponseCallback callback;
- public DefaultFuture(Channel channel, Request request, int timeout){
- this.channel = channel;
- this.request = request;
- this.id = request.getId();
- this.timeout = timeout > 0 ? timeout : channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
- // put into waiting map.
- FUTURES.put(id, this);
- CHANNELS.put(id, channel);
- }
- public Object get() throws RemotingException {
- return get(timeout);
- }
- public Object get(int timeout) throws RemotingException {
- if (timeout <= 0) {
- timeout = Constants.DEFAULT_TIMEOUT;
- }
- if (! isDone()) {
- long start = System.currentTimeMillis();
- lock.lock();
- try {
- while (! isDone()) {
- done.await(timeout, TimeUnit.MILLISECONDS);
- if (isDone() || System.currentTimeMillis() - start > timeout) {
- break;
- }
- }
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } finally {
- lock.unlock();
- }
- if (! isDone()) {
- throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
- }
- }
- return returnFromResponse();
- }
- public void cancel(){
- Response errorResult = new Response(id);
- errorResult.setErrorMessage("request future has been canceled.");
- response = errorResult ;
- FUTURES.remove(id);
- CHANNELS.remove(id);
- }
- public boolean isDone() {
- return response != null;
- }
- public void setCallback(ResponseCallback callback) {
- if (isDone()) {
- invokeCallback(callback);
- } else {
- boolean isdone = false;
- lock.lock();
- try{
- if (!isDone()) {
- this.callback = callback;
- } else {
- isdone = true;
- }
- }finally {
- lock.unlock();
- }
- if (isdone){
- invokeCallback(callback);
- }
- }
- }
- private void invokeCallback(ResponseCallback c){
- ResponseCallback callbackCopy = c;
- if (callbackCopy == null){
- throw new NullPointerException("callback cannot be null.");
- }
- c = null;
- Response res = response;
- if (res == null) {
- throw new IllegalStateException("response cannot be null. url:"+channel.getUrl());
- }
- if (res.getStatus() == Response.OK) {
- try {
- callbackCopy.done(res.getResult());
- } catch (Exception e) {
- logger.error("callback invoke error .reasult:" + res.getResult() + ",url:" + channel.getUrl(), e);
- }
- } else if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
- try {
- TimeoutException te = new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage());
- callbackCopy.caught(te);
- } catch (Exception e) {
- logger.error("callback invoke error ,url:" + channel.getUrl(), e);
- }
- } else {
- try {
- RuntimeException re = new RuntimeException(res.getErrorMessage());
- callbackCopy.caught(re);
- } catch (Exception e) {
- logger.error("callback invoke error ,url:" + channel.getUrl(), e);
- }
- }
- }
- private Object returnFromResponse() throws RemotingException {
- Response res = response;
- if (res == null) {
- throw new IllegalStateException("response cannot be null");
- }
- if (res.getStatus() == Response.OK) {
- return res.getResult();
- }
- if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
- throw new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage());
- }
- throw new RemotingException(channel, res.getErrorMessage());
- }
- private long getId() {
- return id;
- }
- private Channel getChannel() {
- return channel;
- }
- private boolean isSent() {
- return sent > 0;
- }
- public Request getRequest() {
- return request;
- }
- private int getTimeout() {
- return timeout;
- }
- private long getStartTimestamp() {
- return start;
- }
- public static DefaultFuture getFuture(long id) {
- return FUTURES.get(id);
- }
- public static boolean hasFuture(Channel channel) {
- return CHANNELS.containsValue(channel);
- }
- public static void sent(Channel channel, Request request) {
- DefaultFuture future = FUTURES.get(request.getId());
- if (future != null) {
- future.doSent();
- }
- }
- private void doSent() {
- sent = System.currentTimeMillis();
- }
- public static void received(Channel channel, Response response) {
- try {
- DefaultFuture future = FUTURES.remove(response.getId());
- if (future != null) {
- future.doReceived(response);
- } else {
- logger.warn("The timeout response finally returned at "
- + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
- + ", response " + response
- + (channel == null ? "" : ", channel: " + channel.getLocalAddress()
- + " -> " + channel.getRemoteAddress()));
- }
- } finally {
- CHANNELS.remove(response.getId());
- }
- }
- private void doReceived(Response res) {
- lock.lock();
- try {
- response = res;
- if (done != null) {
- done.signal();
- }
- } finally {
- lock.unlock();
- }
- if (callback != null) {
- invokeCallback(callback);
- }
- }
- private String getTimeoutMessage(boolean scan) {
- long nowTimestamp = System.currentTimeMillis();
- return (sent > 0 ? "Waiting server-side response timeout" : "Sending request timeout in client-side")
- + (scan ? " by scan timer" : "") + ". start time: "
- + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(start))) + ", end time: "
- + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())) + ","
- + (sent > 0 ? " client elapsed: " + (sent - start)
- + " ms, server elapsed: " + (nowTimestamp - sent)
- : " elapsed: " + (nowTimestamp - start)) + " ms, timeout: "
- + timeout + " ms, request: " + request + ", channel: " + channel.getLocalAddress()
- + " -> " + channel.getRemoteAddress();
- }
- private static class RemotingInvocationTimeoutScan implements Runnable {
- public void run() {
- while (true) {
- try {
- for (DefaultFuture future : FUTURES.values()) {
- if (future == null || future.isDone()) {
- continue;
- }
- if (System.currentTimeMillis() - future.getStartTimestamp() > future.getTimeout()) {
- // create exception response.
- Response timeoutResponse = new Response(future.getId());
- // set timeout status.
- timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT);
- timeoutResponse.setErrorMessage(future.getTimeoutMessage(true));
- // handle response.
- DefaultFuture.received(future.getChannel(), timeoutResponse);
- }
- }
- Thread.sleep(30);
- } catch (Throwable e) {
- logger.error("Exception when scan the timeout invocation of remoting.", e);
- }
- }
- }
- }
- static {
- Thread th = new Thread(new RemotingInvocationTimeoutScan(), "DubboResponseTimeoutScanTimer");
- th.setDaemon(true);
- th.start();
- }
- }
以DefaultFuture为例,看类变量初始化顺序的更多相关文章
- java 类变量初始化顺序
假定有一个类定义如下: package com.zhang; public final class Girl { // static代码块1 private static String sex = & ...
- Java语法专题2: 类变量的初始化顺序
合集目录 Java语法专题2: 类变量的初始化顺序 问题 这也是Java面试中出镜率很高的基础概念问题 描述一下多级继承中字段初始化顺序 描述一下多级继承中类变量初始化顺序 写出运行以下代码时的控制台 ...
- Java中类的初始化顺序
一.一个类的初始化顺序(没继承情况) 规则: 1.静态变量>普通变量>构造方法 2.变量定义的顺序决定初始化的顺序 3.静态变量和静态块是一样的,普通变量和非静态块是一样的,即能够把 ...
- Java中的成员初始化顺序和内存分配过程
Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...
- 11.c#类的成员初始化顺序
转自http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html C#作为一种纯面向对象的话言,为它编写的整个代码里面到处都离不开对象 ...
- C++——类继承以及类初始化顺序
对于类以及类继承, 几个主要的问题:1) 继承方式: public/protected/private继承. 这是c++搞的, 实际上继承方式是一种允许子类控制的思想. 子类通过public继承, 可 ...
- Java杂谈3——类加载机制与初始化顺序
Java语言的哲学:一切都是对象.对于Java虚拟机而言,一个普通的Java类同样是一个对象,那如果是对象,必然有它的初始化过程.一个类在JVM中被实例化成一个对象,需要经历三个过程:加载.链接和初始 ...
- spring初始化顺序
首先,Spring bean的默认加载顺序是怎么控制的 工程中有2个bean,A和B,其中必须先初始化A再初始化B,但是没有depend-on或者Order等方式去保证,只不过恰好刚好这么运行着没出事 ...
- Java变量、Java对象初始化顺序
局部变量与成员变量: 局部变量分为: 行参:在方法签名中定义的局部变量,随方法的结束而凋亡. 方法内的局部变量:必须在方法内对其显示初始化,从初始化后开始生效,随方法的结束而凋亡. 代码块内的局部变量 ...
随机推荐
- P3868 [TJOI2009]猜数字
[TJOI2009]猜数字 中国剩余定理 求解i=1 to n : x≡a[i] (mod b[i])的同余方程组 设 t= ∏i=1 to n b[i] 我们先求出 i=1 to n : x≡1 ( ...
- Python3.x(windows系统)安装libxml2库
Python3.x(windows系统)安装libxml2库 cmd安装命令: pip install lxml 执行结果: 再执行命令: pip install virtualenv 执行结果:
- IOS项目中的细节处理,如更改状态栏等等
一,状态栏更改为白色 1 在info.plist中添加一个字段:view controller -base status bar 为NO 2 在需要改变状态栏颜色的ViewController中在Vi ...
- Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture
ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成之后,再将这些执行结果 ...
- 51NOD 1046 A^B Mod C
给出3个正整数A B C,求A^B Mod C. 例如,3 5 8,3^5 Mod 8 = 3. Input 3个正整数A B C,中间用空格分隔.(1 <= A,B,C <= 10^9) ...
- Pc端css初始化
@charset "UTF-8"; /**css初始化**/ body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd ...
- HDU 5884 Sort(二分+优先队列)
http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...
- Nginx 随笔
使用包管理工具安装nginx Linux(基于deb) sudo apt-get install nginx Linux(基于rpm) sudo yum install nginx FreeBSD s ...
- win7(64)未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序
注:本文为个人学习摘录,原文地址:http://blog.163.com/rihui_7/blog/static/2122851432013627103337825/ 1.以前在win7 64位系统上 ...
- PHP生成缩略图的一个方法类(转)
//使用如下类就可以生成图片缩略图 class resizeimage { //图片类型 var $type; //实际宽度 var $width; //实际高度 var $height; //改变后 ...