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源码如下:

  1. package com.alibaba.dubbo.remoting.exchange.support;
  2.  
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.Map;
  6. import java.util.concurrent.ConcurrentHashMap;
  7. import java.util.concurrent.TimeUnit;
  8. import java.util.concurrent.locks.Condition;
  9. import java.util.concurrent.locks.Lock;
  10. import java.util.concurrent.locks.ReentrantLock;
  11.  
  12. import com.alibaba.dubbo.common.Constants;
  13. import com.alibaba.dubbo.common.logger.Logger;
  14. import com.alibaba.dubbo.common.logger.LoggerFactory;
  15. import com.alibaba.dubbo.remoting.Channel;
  16. import com.alibaba.dubbo.remoting.RemotingException;
  17. import com.alibaba.dubbo.remoting.TimeoutException;
  18. import com.alibaba.dubbo.remoting.exchange.Request;
  19. import com.alibaba.dubbo.remoting.exchange.Response;
  20. import com.alibaba.dubbo.remoting.exchange.ResponseCallback;
  21. import com.alibaba.dubbo.remoting.exchange.ResponseFuture;
  22.  
  23. /**
  24. * DefaultFuture.
  25. *
  26. * @author qian.lei
  27. * @author chao.liuc
  28. */
  29. public class DefaultFuture implements ResponseFuture {
  30. private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class);
  31. private static final Map<Long, Channel> CHANNELS = new ConcurrentHashMap<Long, Channel>();
  32. private static final Map<Long, DefaultFuture> FUTURES = new ConcurrentHashMap<Long, DefaultFuture>();
  33. // invoke id.
  34. private final long id;
  35. private final Channel channel;
  36. private final Request request;
  37. private final int timeout;
  38. private final Lock lock = new ReentrantLock();
  39. private final Condition done = lock.newCondition();
  40. private final long start = System.currentTimeMillis();
  41. private volatile long sent;
  42. private volatile Response response;
  43. private volatile ResponseCallback callback;
  44. public DefaultFuture(Channel channel, Request request, int timeout){
  45. this.channel = channel;
  46. this.request = request;
  47. this.id = request.getId();
  48. this.timeout = timeout > 0 ? timeout : channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
  49. // put into waiting map.
  50. FUTURES.put(id, this);
  51. CHANNELS.put(id, channel);
  52. }
  53. public Object get() throws RemotingException {
  54. return get(timeout);
  55. }
  56. public Object get(int timeout) throws RemotingException {
  57. if (timeout <= 0) {
  58. timeout = Constants.DEFAULT_TIMEOUT;
  59. }
  60. if (! isDone()) {
  61. long start = System.currentTimeMillis();
  62. lock.lock();
  63. try {
  64. while (! isDone()) {
  65. done.await(timeout, TimeUnit.MILLISECONDS);
  66. if (isDone() || System.currentTimeMillis() - start > timeout) {
  67. break;
  68. }
  69. }
  70. } catch (InterruptedException e) {
  71. throw new RuntimeException(e);
  72. } finally {
  73. lock.unlock();
  74. }
  75. if (! isDone()) {
  76. throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false));
  77. }
  78. }
  79. return returnFromResponse();
  80. }
  81.  
  82. public void cancel(){
  83. Response errorResult = new Response(id);
  84. errorResult.setErrorMessage("request future has been canceled.");
  85. response = errorResult ;
  86. FUTURES.remove(id);
  87. CHANNELS.remove(id);
  88. }
  89.  
  90. public boolean isDone() {
  91. return response != null;
  92. }
  93.  
  94. public void setCallback(ResponseCallback callback) {
  95. if (isDone()) {
  96. invokeCallback(callback);
  97. } else {
  98. boolean isdone = false;
  99. lock.lock();
  100. try{
  101. if (!isDone()) {
  102. this.callback = callback;
  103. } else {
  104. isdone = true;
  105. }
  106. }finally {
  107. lock.unlock();
  108. }
  109. if (isdone){
  110. invokeCallback(callback);
  111. }
  112. }
  113. }
  114. private void invokeCallback(ResponseCallback c){
  115. ResponseCallback callbackCopy = c;
  116. if (callbackCopy == null){
  117. throw new NullPointerException("callback cannot be null.");
  118. }
  119. c = null;
  120. Response res = response;
  121. if (res == null) {
  122. throw new IllegalStateException("response cannot be null. url:"+channel.getUrl());
  123. }
  124.  
  125. if (res.getStatus() == Response.OK) {
  126. try {
  127. callbackCopy.done(res.getResult());
  128. } catch (Exception e) {
  129. logger.error("callback invoke error .reasult:" + res.getResult() + ",url:" + channel.getUrl(), e);
  130. }
  131. } else if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
  132. try {
  133. TimeoutException te = new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage());
  134. callbackCopy.caught(te);
  135. } catch (Exception e) {
  136. logger.error("callback invoke error ,url:" + channel.getUrl(), e);
  137. }
  138. } else {
  139. try {
  140. RuntimeException re = new RuntimeException(res.getErrorMessage());
  141. callbackCopy.caught(re);
  142. } catch (Exception e) {
  143. logger.error("callback invoke error ,url:" + channel.getUrl(), e);
  144. }
  145. }
  146. }
  147.  
  148. private Object returnFromResponse() throws RemotingException {
  149. Response res = response;
  150. if (res == null) {
  151. throw new IllegalStateException("response cannot be null");
  152. }
  153. if (res.getStatus() == Response.OK) {
  154. return res.getResult();
  155. }
  156. if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) {
  157. throw new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage());
  158. }
  159. throw new RemotingException(channel, res.getErrorMessage());
  160. }
  161.  
  162. private long getId() {
  163. return id;
  164. }
  165.  
  166. private Channel getChannel() {
  167. return channel;
  168. }
  169.  
  170. private boolean isSent() {
  171. return sent > 0;
  172. }
  173.  
  174. public Request getRequest() {
  175. return request;
  176. }
  177.  
  178. private int getTimeout() {
  179. return timeout;
  180. }
  181.  
  182. private long getStartTimestamp() {
  183. return start;
  184. }
  185.  
  186. public static DefaultFuture getFuture(long id) {
  187. return FUTURES.get(id);
  188. }
  189.  
  190. public static boolean hasFuture(Channel channel) {
  191. return CHANNELS.containsValue(channel);
  192. }
  193.  
  194. public static void sent(Channel channel, Request request) {
  195. DefaultFuture future = FUTURES.get(request.getId());
  196. if (future != null) {
  197. future.doSent();
  198. }
  199. }
  200.  
  201. private void doSent() {
  202. sent = System.currentTimeMillis();
  203. }
  204.  
  205. public static void received(Channel channel, Response response) {
  206. try {
  207. DefaultFuture future = FUTURES.remove(response.getId());
  208. if (future != null) {
  209. future.doReceived(response);
  210. } else {
  211. logger.warn("The timeout response finally returned at "
  212. + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
  213. + ", response " + response
  214. + (channel == null ? "" : ", channel: " + channel.getLocalAddress()
  215. + " -> " + channel.getRemoteAddress()));
  216. }
  217. } finally {
  218. CHANNELS.remove(response.getId());
  219. }
  220. }
  221.  
  222. private void doReceived(Response res) {
  223. lock.lock();
  224. try {
  225. response = res;
  226. if (done != null) {
  227. done.signal();
  228. }
  229. } finally {
  230. lock.unlock();
  231. }
  232. if (callback != null) {
  233. invokeCallback(callback);
  234. }
  235. }
  236.  
  237. private String getTimeoutMessage(boolean scan) {
  238. long nowTimestamp = System.currentTimeMillis();
  239. return (sent > 0 ? "Waiting server-side response timeout" : "Sending request timeout in client-side")
  240. + (scan ? " by scan timer" : "") + ". start time: "
  241. + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date(start))) + ", end time: "
  242. + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date())) + ","
  243. + (sent > 0 ? " client elapsed: " + (sent - start)
  244. + " ms, server elapsed: " + (nowTimestamp - sent)
  245. : " elapsed: " + (nowTimestamp - start)) + " ms, timeout: "
  246. + timeout + " ms, request: " + request + ", channel: " + channel.getLocalAddress()
  247. + " -> " + channel.getRemoteAddress();
  248. }
  249.  
  250. private static class RemotingInvocationTimeoutScan implements Runnable {
  251.  
  252. public void run() {
  253. while (true) {
  254. try {
  255. for (DefaultFuture future : FUTURES.values()) {
  256. if (future == null || future.isDone()) {
  257. continue;
  258. }
  259. if (System.currentTimeMillis() - future.getStartTimestamp() > future.getTimeout()) {
  260. // create exception response.
  261. Response timeoutResponse = new Response(future.getId());
  262. // set timeout status.
  263. timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT);
  264. timeoutResponse.setErrorMessage(future.getTimeoutMessage(true));
  265. // handle response.
  266. DefaultFuture.received(future.getChannel(), timeoutResponse);
  267. }
  268. }
  269. Thread.sleep(30);
  270. } catch (Throwable e) {
  271. logger.error("Exception when scan the timeout invocation of remoting.", e);
  272. }
  273. }
  274. }
  275. }
  276.  
  277. static {
  278. Thread th = new Thread(new RemotingInvocationTimeoutScan(), "DubboResponseTimeoutScanTimer");
  279. th.setDaemon(true);
  280. th.start();
  281. }
  282.  
  283. }

以DefaultFuture为例,看类变量初始化顺序的更多相关文章

  1. java 类变量初始化顺序

    假定有一个类定义如下: package com.zhang; public final class Girl { // static代码块1 private static String sex = & ...

  2. Java语法专题2: 类变量的初始化顺序

    合集目录 Java语法专题2: 类变量的初始化顺序 问题 这也是Java面试中出镜率很高的基础概念问题 描述一下多级继承中字段初始化顺序 描述一下多级继承中类变量初始化顺序 写出运行以下代码时的控制台 ...

  3. Java中类的初始化顺序

    一.一个类的初始化顺序(没继承情况)  规则: 1.静态变量>普通变量>构造方法   2.变量定义的顺序决定初始化的顺序 3.静态变量和静态块是一样的,普通变量和非静态块是一样的,即能够把 ...

  4. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  5. 11.c#类的成员初始化顺序

    转自http://www.cnblogs.com/siceblue/archive/2009/01/15/1376430.html C#作为一种纯面向对象的话言,为它编写的整个代码里面到处都离不开对象 ...

  6. C++——类继承以及类初始化顺序

    对于类以及类继承, 几个主要的问题:1) 继承方式: public/protected/private继承. 这是c++搞的, 实际上继承方式是一种允许子类控制的思想. 子类通过public继承, 可 ...

  7. Java杂谈3——类加载机制与初始化顺序

    Java语言的哲学:一切都是对象.对于Java虚拟机而言,一个普通的Java类同样是一个对象,那如果是对象,必然有它的初始化过程.一个类在JVM中被实例化成一个对象,需要经历三个过程:加载.链接和初始 ...

  8. spring初始化顺序

    首先,Spring bean的默认加载顺序是怎么控制的 工程中有2个bean,A和B,其中必须先初始化A再初始化B,但是没有depend-on或者Order等方式去保证,只不过恰好刚好这么运行着没出事 ...

  9. Java变量、Java对象初始化顺序

    局部变量与成员变量: 局部变量分为: 行参:在方法签名中定义的局部变量,随方法的结束而凋亡. 方法内的局部变量:必须在方法内对其显示初始化,从初始化后开始生效,随方法的结束而凋亡. 代码块内的局部变量 ...

随机推荐

  1. 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 ( ...

  2. Python3.x(windows系统)安装libxml2库

    Python3.x(windows系统)安装libxml2库 cmd安装命令: pip install lxml 执行结果: 再执行命令: pip install virtualenv 执行结果:

  3. IOS项目中的细节处理,如更改状态栏等等

    一,状态栏更改为白色 1 在info.plist中添加一个字段:view controller -base status bar 为NO 2 在需要改变状态栏颜色的ViewController中在Vi ...

  4. Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture

    ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成之后,再将这些执行结果 ...

  5. 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) ...

  6. Pc端css初始化

    @charset "UTF-8"; /**css初始化**/ body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd ...

  7. HDU 5884 Sort(二分+优先队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=5884 题意:有个屌丝设计了一个程序,每次可以将k个数组进行合并,代价为这k个数组总的长度之和.现在另外一个屌丝要 ...

  8. Nginx 随笔

    使用包管理工具安装nginx Linux(基于deb) sudo apt-get install nginx Linux(基于rpm) sudo yum install nginx FreeBSD s ...

  9. win7(64)未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序

    注:本文为个人学习摘录,原文地址:http://blog.163.com/rihui_7/blog/static/2122851432013627103337825/ 1.以前在win7 64位系统上 ...

  10. PHP生成缩略图的一个方法类(转)

    //使用如下类就可以生成图片缩略图 class resizeimage { //图片类型 var $type; //实际宽度 var $width; //实际高度 var $height; //改变后 ...