制作自己的docker tomcat image

制作自己的dockfile image

新建文本文件: Dockerfile (没有后缀), 里面内容如下:

FROM tomcat:7.0
RUN rm -rf /usr/local/tomcat/webapps/ROOT
ADD http://ci.qa.tianxiaohui.com/job/bnrdash-r2-2_job_Eric/197/artifact/bnrdash/target/ROOT.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]

每一行解释:
1) 基于公共的tomcat:7.0 的image, 更多tomcat image 看这里 https://registry.hub.docker.com/_/tomcat/
2) 因为我自己的包是ROOT.war, 所以把tomcat 再带的删除, 也为了安全, 当然其它自带的最好也删除
3) 把CI做好的war 文件ccopy 进去
4) 默认启动tomcat

使用下面的命令打包(最后的点表示当前目录去找 Dockerfile):

docker build -t xiatian/tomcatBnrdash .

查看local的images, 已经包含最新的

docker images

那么就可以去run了, 下面分别开8081, 8082, 开了2个containers.

docker run -d -p 8081:8080 xiatian/tomcatBnrdash
docker run -d -p 8082:8080 xiatian/tomcatBnrdash

查看正在运行的container

docker ps

进入正在运行的container

docker exec -it  CONTAINER_ID bash

Java Collection Framework List, Set, Queue, Deque 关系图

使用 https://www.draw.io/ 在线画的, 只涉及到List, Set, Queue, Deque. 只包含util 包里面的类和接口.
接口以圆角长方形表示, 类以直角长方形表示.

在线浏览版本: https://drive.google.com/file/d/0B6ry0l2WQQIjclhSSGZyNGgxX1k/view?usp=sharing

离线下载版本, 下面 png 格式图片, 可以另存为, 放大. 也可以下载pdf 格式
pdf version: JavaCollection.pdf
JavaCollection.png

tomcat 配置在linux上, 机器重启后 自动启动

#!/bin/bash

### BEGIN INIT INFO
# Provides:        tomcat7
# Required-Start:  $network
# Required-Stop:   $network
# Default-Start:   2 3 4 5
# Default-Stop:    0 1 6
# Short-Description: Start/Stop Tomcat server
### END INIT INFO

PATH=/sbin:/bin:/usr/sbin:/usr/bin

start() {
 sh /opt/apache-tomcat-7.0.59/bin/startup.sh
}

stop() {
 sh /opt/apache-tomcat-7.0.59/bin/shutdown.sh
}

case $1 in
  start|stop) $1;;
  restart) stop; start;;
  *) echo "Run as $0 <start|stop|restart>"; exit 1;;
esac

chmod 755 /etc/init.d/tomcat7
update-rc.d tomcat7 defaults

另外一种写法

 #!/bin/sh
 #tomcat auto-start
 case $1 in
        start)
            sh /opt/apache-tomcat-7.0.59/bin/startup.sh;;
        stop)
            sh /opt/apache-tomcat-7.0.59/bin/shutdown.sh;;
        restart)
            sh /opt/apache-tomcat-7.0.59/bin/shutdown.sh
            sh /opt/apache-tomcat-7.0.59/bin/startup.sh;;
        *)
            echo 'Usage:tomcat7 start|stop|restart';;
    esac
    exit 0

从这里抄过来的: http://askubuntu.com/questions/223944/how-to-automatically-restart-tomcat7-on-system-reboots

Java Executor Framework

Executor Framework

Executor framework 以Executor接口为核心, 有ExecutorService 和 ScheduledExecutorService 2 个子接口, 提供了线程创建, 销毁的快捷方式, 并且线程可以做到复用.

Runnable VS Callable

1) Callable 提供的call() 方法, 可以异步返回结果, 可以throw checked Exception;
2) ExecutorService 接口可以通过 submit, invokeAny, invokeAll 去执行Callable 接口, 返回Future.

ExecutorService

shutdown() 和 shutdownNow() 的区别在于是否执行pending的task.
如果当前线程要等待ExecutorService的线程都执行完, 必须调用shutdown / shutdownNow, 然后调用
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException.
invokeAny() 方法返回最快的一个Task 结果, 如果第一个有Exception, 一次找后面比较快的, 如果都有异常, 则返回异常.

Future

ExecutorService 的 submit(), invokeAll(), invokeAny() 都返回Future对象, 它能track Callable 执行的状态, 能cancel Callable.

FutureTask

FutureTask 实现了Runnable, Future, RunnableFuture 接口.
因为实现了Runnable接口, 所以可以被Thread, ExecutorService执行.
因为实现了Future 接口, 所以可以track status, 可以被cancel;
构造函数可以封装 Runnable 和 Callable.

一张图总结一下:
box-598143524220884.jpg

线程同步工具类[2]

Phaser

适用于分阶段的线程同步. 可以在构造时设置一个初始的参与的线程个数, 也可以后边通过方法注册与注销. 所以它的生命周期内参与的线程数是可以变化的. 当其中参与的线程到达某个phase的确认点之后, 可以选择等待,或直接继续, 或者不参与到下一个phase.
Phaser内部维护phase的数值, 记录当前那些phase到达的数量, 但是不会维护参与者的信息. 这里有个很重要的概念是: Phase 并不管有多少线程, 它只管每个阶段达到方法被调用的次数, 只要被调用的次数足够, 它就到下一阶段, 典型的是Phaser的注册数有N个, 但是这N全是一个线程在调用arrive() 方法. 当然如果是要求多个同步, 一般是多个线程调用arriveAndAwaitAdvance(). 这个phase 数值从0 开始, 当要求的参与者都到达之后加一.

public int arrive() 方法不会等待其他参与者, 当此线程下次调用相关的arrive*()方法的时候, 有可能还是当前phase, 是当前phase的到达者加一. 如

public static void main(String[] args) {
    Phaser p = new Phaser(3);
    
    System.out.println(p.arrive());
    System.out.println(p.arrive());
    System.out.println(p.arrive());
    
    System.out.println(p.arrive());
    System.out.println(p.arrive());
    System.out.println(p.arrive());
    p.forceTermination();
}

public int arriveAndAwaitAdvance() 方法等同于awaitAdvance(arrive()), 和 CyclicBarrier的await() 方法类似.

不等待: arrive();
不等待并且使参与者减少一个: arriveAndDeregister()
等待这一个phase结束并且使参与者减少一个: awaitAdvance(arriveAndDeregister())

public int awaitAdvance(int phase) 这个方法很容易让人迷糊, 以为它会一直等待第N phase, 其实不然, 只要是当前phase 和N 不相等, 就立马返回. 所以, 如果你想真正的等待第N phase, 那么你可能需要这么做:

    while (p.getPhase() < N) {
        p.awaitAdvance(p.getPhase()); // 前提是你N之前都没注册
    }
    //此处已到N或者N+

protected boolean onAdvance(int phase, int registeredParties) 方法是在所有参与者到达后, 下一phase 开始之前执行的, 类似CyclicBarrier 的Action Command. 这个方法可以用来override 去替换一些特定的Action. 如果返回值是true, 则本phase 是最后一个阶段.
如果Phaser 已经终止, 则后面的await都会立马返回.

Exchanger

在一个同步点, 2个线程彼此通过Exchanger交换数据.