chapt2 java并行程序基础
读完原书第二章,记录下一些要点
1. 关于线程中断
public class InterruptThread implements Runnable{
@Override
public void run() {
Thread.currentThread().setName("jeyawn thread");
while (true) {
if(Thread.currentThread().isInterrupted()) {
System.out.println("interrup called");
break;
}
try {
System.out.println("before sleep");
Thread.sleep(1000000000000L);
System.out.println("after sleep");
}
catch (InterruptedException e) {
System.out.println("we have excetion:");
if(Thread.currentThread().isInterrupted()) {
System.out.println("current thread interrupted.....");
}
Thread.currentThread().interrupt();
}
}
System.out.println("Thread exit.......");
}
}
public static void Test1() {
String name = ManagementFactory.getRuntimeMXBean().getName();
System.out.println(name);
// get pid
String pid = name.split("@")[0];
System.out.println("pid===>"+pid);
Thread t1 = new Thread(new InterruptThread());
t1.start();
try {
Thread.sleep(3000);
}
catch (Exception e) {
e.printStackTrace();
}
t1.interrupt();
}
这里需要几个注意点
interrupt 方法可以制造中断,在线程那边会收到InterruptedException ,此时中断标记已经清除,需要继续Thread.currentThread().interrupt() 设置中断。
isInterrupted 可以判断当前线程是否被中断
2. java 线程查看方法:
获取当前进程pid的方法:
String name = ManagementFactory.getRuntimeMXBean().getName();
System.out.println(name);
// get pid
String pid = name.split("@")[0];
System.out.println("pid===>"+pid);
通过jstack命令可以查看线程状态,例如如下: jstack -l pid
C:\Program Files\Java\jdk1.8.0_191\bin>jstack -l 32556
2019-05-01 15:03:08
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode):
"DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x0000000002f52800 nid=0x5244 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"jeyawn thread" #11 prio=5 os_prio=0 tid=0x0000000019409800 nid=0x6270 waiting on condition [0x000000001a05f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.jeyawn.threadimpl.InterruptThread.run(InterruptThread.java:23)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x0000000019408800 nid=0x7724 runnable [0x0000000019f5f000]
3.volatile 的使用
volatile这个东西只是表示当前修饰的东西是易变的,jvm在使用的时候需要主动刷新,它不能替代锁,因此也无法保证原子性。实际上,它具有的功能,synchronized都具有,建议以后还是用synchronized替代volatile。
这里还引出来一个全局变量共享访问的事情:
不要简单的用全局变量(除非加volatile)来作为两个线程的通信,也许永远不会奏效。
public class NoVisibility {
private static int number;
private static boolean ready;
private static class ReaderThread extends Thread {
@Override
public void run() {
int i = 0;
while (!ready) {
i++;
// if(i%100000000 == 0) {
// System.out.println("ready==>"+ready);
// }
}
System.out.println("number:"+number);
}
}
public static void doTest() throws InterruptedException {
new ReaderThread().start();
Thread.sleep(1000L);
number = 1000;
ready = true;
Thread.sleep(10000);
}
}
上面这段代码在ready没有用volatile修饰的时候,reader线程没法看到ready变成true的这个动作,所以永远不会退出循环(我在jdk9,client模式试的)。但是奖赏一些打印之后(就是被注释掉的代码),这块的代码又能看到ready变成true这个情况,所以说,对于这样的情况需要很小心!!!!
4. 其它
非线程安全的数据结构 ArrayList, HashMap
线程安全:Vector, ConcurrentHashMap,CopyOnWriteArrayList(比Vector效率高)