美文网首页程序员
Java并发编程的艺术-并发编程的基础

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

作者: 油多坏不了菜 | 来源:发表于2019-02-25 23:37 被阅读2次

线程的状态

  • NEW
  • RUNNABLE
  • BLOCKED:线程阻塞于锁
  • WAITING:等待状态,当前线程需要等待其他线程通知或者中断才能被唤醒。
  • TIME_WAITING:超时等待,与waiting状态不同的是,它可以在指定的时间到达时返回到运行状态,不一定需要别的线程的唤醒。
  • TERMINATED

线程状态变迁

  • 从RUNNABLE变为WAITING状态可能的情况
object.wait();//等待object.notify()或者object.notifyAll();
threadA.join();//等待线程threadA执行完毕
LockSupport.park();//important,等待相应的uppark调用。
  • 从RUNNABLE到TIME_WAITING类似于上,只是加上了超时返回。
Thread.sleep(long);
object.wait(long);
threadA.join(long);
LockSupport.park(long);
  • 从RUNNABLE到阻塞状态
    等待进入synchronized方法和synchronized代码块。注意:阻塞在concurrent包中的Lock接口的线程是等待状态(因为底层使用的LockSupport类中的方法)

线程的创建与销毁

线程的创建

新建一个线程对象时: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中存储的键值对绑定到线程,当其中的值不再使用时需要置空以便垃圾回收。可以用于方法调用计时。

相关文章

网友评论

    本文标题:Java并发编程的艺术-并发编程的基础

    本文链接:https://www.haomeiwen.com/subject/wrdnyqtx.html