线程的使用经验(设置名称、响应中断、使用ThreadLocal)

启动线程的注意事项

方式一

1
2
3
4
5
6
Thread thread = new Thread("thread name") {
public void run() {
// do xxx
}
};
thread.start();

方式二

1
2
3
4
5
6
7
8
9
10
11
public class MyThread extends Thread {
public MyThread() {
super("thread name");
}
public void run() {
// do xxx
}
};
MyThread thread = new MyThread ();
thread.start();

方式三

1
2
3
4
5
6
7
Thread thread = new Thread() {
public void run() {
// do xxx
}
};
thread.setName("thread name");
thread.start();

方式四

1
2
3
4
Thread thread = new Thread(task);
// 传入任务
thread.setName(“thread name");
thread.start();

方式五

1
2
Thread thread = new Thread(task, “thread name");
thread.start();

无论何种方式,启动一个线程,就要给它一个名字!这对排错诊断系统监控有帮助。否则诊断问题时,无法直观知道某个线程的用途。

要响应线程中断

thread.interrupt();
方式一

1
2
3
4
5
6
7
8
9
10
11
Thread thread = new Thread("interrupt test") {
public void run() {
for (;;) {
doXXX();
if (Thread.interrupted()) {
break;
}
}
}
};
thread.start();

方式二

1
2
3
4
5
public void foo() throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
}

方式三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Thread thread = new Thread("interrupt test") {
public void run() {
for (;;) {
try {
doXXX();
} catch (InterruptedException e) {
break;
} catch (Exception e) {
// handle Exception
}
}
}
};
thread.start();

程序应该对线程中断作出恰当的响应。

ThreadLocal

+-------------+---------+
|     ThreadLocal<T>    |
+-------------+---------+
+-------------+---------+
| initialValue() : T    |
| get() : T             |
| set(T value)          |
| remove()              |
+-------------+---------+

顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不 会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。

使用场景

  • To keep state with a thread (user-id, transaction-id, logging-id)
  • To cache objects which you need frequently
  • 隐式传参

注意:使用ThreadLocal,一般都是声明在静态变量中,如果不断的创建ThreadLocal而且没有调用其remove方法,将会导致内存泄露
同时请注意,如果是static的ThreadLocal,一般不需要调用remove。

线程间的协调(lock、condition、wait、notify、notifyAll)

ReentrantLock和Synchronized

Synchronized是Lock的一种简化实现,一个Lock可以对应多个Condition,而synchronized把Lock和Condition合并了,一个synchronized Lock只对应一个Condition,可以说Synchronized是Lock的简化版本。
在JDK 5,Synchronized要比Lock慢很多,但是在JDK 6中,它们的效 率差不多。

不要在Lock和Condition上使用wait、notiffy、notifyAll方法!