程序员

Java并发编程的艺术-并发编程的基础

2019-02-25  本文已影响2人  油多坏不了菜

线程的状态

线程状态变迁

object.wait();//等待object.notify()或者object.notifyAll();
threadA.join();//等待线程threadA执行完毕
LockSupport.park();//important,等待相应的uppark调用。
Thread.sleep(long);
object.wait(long);
threadA.join(long);
LockSupport.park(long);

线程的创建与销毁

线程的创建

新建一个线程对象时:init方法会从其父线程(当前线程)继承一些信息,比较重要的有(contextClassLoader,daemon,priority,可继承的ThreadLocal)

线程的启动

thread.start();

中断

中断就相当与线程与线程之间发消息一样,假如threadA中调用threadB.interrupt(), 那么threadB就会收到这个中断消息并做出响应(比如,threadB正在sleep,那么sleep会马上结束并抛出InterruptedException)
对thread.isInterrupted()和Thread.interrupted(检查当前线程中断表示位)的返回值取决与线程是否还有未被处理的中断消息。对于上面的例子来说,thread.isInterrupted()返回false,因为中断消息已经被消耗了(返回InterruptedException)

安全的终止线程demo

通过这个Runner生成的线程对象可以通过中断关闭,或者cancel()调用关闭

private static class Runner implements Runnable{
        private volatile boolean on = true;
        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()){
                //do 
            }
        }
          public void cancel() {
                  on = false;
          }
    }

线程间通信

volatile和synchronized关键字的内存语义

等待通知机制

这里主要涉及Object类的几个方法

wait();
wait(long);//超时等待
notify();
notifyAll();

这里以一段生产者消费者代码,这样写有点冗余。

  private class Container{
        private int maxCap;
        private int curCap;
        private int toPut;
        private int toGet;
        private int[] data;
        Container(int cap){
            this.maxCap = cap;
            data = new int[cap];
            curCap = toGet = toPut = 0;
        }
        public int get(){
            synchronized (this){
                while (curCap <= 0)
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                int tmp = data[toGet];
                curCap--;
                toGet = toGet + 1 < maxCap ? toGet + 1: 0;
                this.notifyAll();//this can notify the consumer thread also.
                return tmp;
            }
        }
        public void put(int i){
            synchronized (this){
                while (curCap == maxCap){
                    try{
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                data[toPut] = i;
                curCap ++;
                toPut = toPut + 1 < maxCap ? toPut + 1 : 0;
                this.notifyAll();
            }
        }
    }

Thread.join()

如在threadA中调用threadB.join()那么就会等threadB返回之后才执行A线程中threadB.join()之后的内容。
这里其实是相当于 threadB.wait(); 然后线程销毁时threadB.notifyAll();

ThreadLocal

ThreadLocal中存储的键值对绑定到线程,当其中的值不再使用时需要置空以便垃圾回收。可以用于方法调用计时。

上一篇 下一篇

猜你喜欢

热点阅读