实战java高并发程序设计学习(1)

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效率高)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值