单例模式 -> ThreadLocal -> new

Java 是多线程, 面向对象的编程语言. 多线程有时候也需要 share 一个实例对象. 一个 JVM 中的多线程可能会产生如下的 share 模式:

  1. 所有线程使用同一个实例对象: 单例模式;
  2. 每个线程使用一个实例对象: ThreadLocal;
  3. 最普遍的, 一个实例对象就是内存堆中的一个实例对象: new

如何做到一个 JVM 中的 单例模式:

  1. 构造函数全都是 private
  2. 因为构造函数是 private, 所以只能该 class 提供一个唯一内部的 static instance. 该 static instance 可以通过 public 暴露, 或者通过一个 public static 方法暴露. 通过方法暴露, 可以 lazy init;

其实, 如上并不能保证一个 JVM 中只有一个 instance, 比如2个 ClassLoader 在同一级, 分别 load 该 class, 或者反序列化该类;

ThreadLocal

前面要加 static final 修饰符. 不加 static, 不能确保一个线程只有一个实例. 不加 final, 可能会被改变的

How to create a java object?

  1.    new Object();
    
  2.    Class.forName(“com.txhcqy.A”).newInstance();
    
  3.    反序列化
    
  4.    反射机制中的Constructor
    

git 学习笔记 之 服务器上的 Git

原书中文版网址: here

为什么需要远程 git repo? 共享, 合作, 集成, 备份?
本地 repo <- pull, push -> 远程 repo
远程 repo 没有人在开发 -> no work directory -> so bare repository -> just need files in .git folder
git repo 所管理的所有东西, 都是 .git 目录下的文件 -> 它根据 git 自己定义的组织结构存在

架设 "git server" -> 通信 -> 选择协议 (file, ssh, http/https, git).

file 本地共享, 方便, 不安全, 灾难备份, 有时候许挂载;
ssh 同时支持 读, 写的网络协议, ssh 最常见, 安全, 基于用户名密码访问, 不利于共享, 和匿名访问;
git 自带的守护线程(9418), 需要 git-daemon-export-ok 文件, 没有加密&授权机制, 要么全部允许推送, 要么全部不允许;
http/https 简便, 便于分享, 需要 post-update hook, 如果需要推送 -> WebDAV, 端口常见, 效率低

"git server" 的关键点在于管理用户权限, ssh for each user? or shared account? or LDAP integratoin?

gitosis 可以帮我们管理 authorized_keys 中所有的 public key;
貌似Gitolite 更强大, 管理的细节竟然到了某 branch, refs 了.

服务器上的 git, 而不是 git server

上周看到 ddwrt 的 repo 中有 git, 就突发奇想, 是不是可以在路由器上搭一个 git server.
后来发现, 其实并没有 git server, 只有 server 上的 git.

首先, git 维护的是 .git 目录下面的所有文件和文件夹, repo 之间 push/pull 的效果是: .git 目录下面文件的相互 copy.
服务器上的 git 默认是没有监听线程的, 所以如果你 push, 其实是把文件 copy 到 server 上的某个 .git 文件夹下面. 一般我们用的还是 ssh 协议, 其实类是你 ssh 登录到 server, 然后用 vi 写 .git 文件夹下的文件.

所以最简单的 "git server" 是你在一个大家都可以访问的 server 初始化一个存放 .git 文件夹下所有文件的目录. 然后开放 ssh 协议, 凡是能够 ssh 登上这台 server 的人, 可以可以 push. pull 就是完全 copy 下来.

之所以有 git server 的惯性思维, 是因为我们经常用 github, gitlab 这样的 git web 管理 server, 是这些 web server 给了我们一个浏览我们 git 保存的历史版本的工具.

除了 github, gitlab (免费)之外, 还有一些比较方便的共享 repo 的方法 8 ways to share your git repository

另外: 服务器上的 Git - 协议

NCR 访问 google.com 而不是 google.com.hk

为了搜个英文材料, google 总是自动跳转到 google.com.hk 即使点了右下角的 使用 google.com 仍旧跳转到 hk. 登录 google 帐号, 也不可以, 使用代理也不可以.

搜了一下, 如果访问 http://www.google.com/ncr 就能访问 google.com 的服务了.
据说这个 NCR 是 No Country Redirect 的意思.

java monitor lock

每个 Java 对象都关联一个 monitor, 运行的线程可以对 monitor 进行 lock 或者 unlock. 同一时刻, 只能有一个线程获得一个对象的锁, 其它尝试获得此锁的线程都被 block 住, 直到当前线程释放此锁.

要使用 java.lang.Object 的 wait, notify 方法, 必须获得此对象的 monitor 的 lock, 所以 wait, notify, notifyAll 必须在获得此锁的 synchronized 的代码块中.

最基本的线程等待, 是使用 while(true) { //break 条件 或启动新线程/进程去做事;}, 但是这种是一直占用 CPU, 称之为 busy waiting. 如果想暂时不占 CPU 可以让线程 inactive, 等到一定条件唤醒线程. java 让线程 inactive 的方法是 wait(), wait(时间); 唤醒的方式是 notify, notifyAll,(必须是同一个对象), 或者 发出interupt 信号.

另外一个让线程暂时休眠的方法是 Thread.currentThread().sleep(时间). 让线程暂时休眠固定的时间, 倒是自动醒来, 不需要唤醒.

参考: Chapter 17. Threads and Locks