美文网首页javajava编程相关
《java多线程编程核心技术》读书笔记

《java多线程编程核心技术》读书笔记

作者: 捉影T_T900 | 来源:发表于2018-08-28 00:24 被阅读2次

    最近读完了《java多线程编程核心技术》(高洪岩)、《Android高性能编程》(叶坤 译)、《Java RESTful Web Service实战 (第2版)》(韩陆),觉得有必要记录下。先从《java多线程编程核心技术》开始。
    废话不多说,上思维导图


    java多线程编程核心技术.png

    1、线程常用方法

    (1)继承Thread、实现Runnable接口
    (2)共享数据可能会出现线程不安全问题
    (3)isAlive 判断线程是否处于活动状态
    (4)sleep 线程进入休眠
    (5)停止线程

    this.interrupted()  测试当前线程是否已经是中断状态,执行后对状态有清除为false的功能
    this.isInterrupted() 测试线程Thread对象是否已经是中断状态,但不清除状态标志
    可以通过Throw new Exception中断线程运行
    stop方法已经不建议继续使用
    

    (6)暂停、恢复线程
    suspend、resume 该组方法有独占、不同步的缺点
    yield放弃当前占用的cpu资源,但暂停时间不确定
    (7)线程可以设置优先级 1~10的级别,默认5,最小1,最大10,小于1或者大于10都会抛异常

    2、对象及变量的并发访问

    synchronized保护的是对象

    同步实例方法(同步当前对象)
    int count = 0;
    public synchronized void add() {
      count++;
    }
    
    同步静态方法(同步当前类)
    static int count = 0;
    public static synchronized void add() {
      count++;
    }
    
    同步代码块
    (实例,同步当前对象)
    int count = 0;
    public void add() {
      synchronized(this) {
        count++;
      }
    }
    (静态,同步当前类)
    static int count = 0;
    public static void add() {
      synchronized(Counter.class) {
        count++;
      }
    } 
    (使用单独对象作为锁)
    int count = 0;
    Object object = new Object();
    public void add() {
      synchronized(object) {
        count++;
      }
    }
    

    可重入性/内存可见性/死锁
    volatile 变量存在于线程外部的内存空间,能保证变量是最新值,只能保证可见性,不能保证原子性,就是说不能保证变量的同步安全。

    3、线程间通信

    (1)等待/通知机制
    wait方法是Object类的方法,必须要配合监视器(synchronized)一起使用,监视器监视的是对象。

        public static void main(String[] args) {
            try {
                Object lock = new Object();
                ThreadA threadA = new ThreadA(lock);
                threadA.start();
                Thread.sleep(2000);
                
                ThreadB threadB = new ThreadB(lock);
                threadB.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        
        public static class ThreadA extends Thread {
            
            private Object lock;
            
            public ThreadA(Object lock) {
                this.lock = lock;
            }
            
            @Override
            public void run() {
                try {
                    synchronized (lock) {
                        System.out.println("开始  wait time:" + System.currentTimeMillis());
                        lock.wait();
                        System.out.println("结束  wait time:" + System.currentTimeMillis());
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        
        public static class ThreadB extends Thread {
            
            private Object lock;
            
            public ThreadB(Object lock) {
                this.lock = lock;
            }
            
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("开始  notify time:" + System.currentTimeMillis());
                    lock.notify();
                    System.out.println("结束  notify time:" + System.currentTimeMillis());
                }
            }
        }
    

    notifyAll 可以唤醒所有持有该对象锁的线程,让其继续执行剩余的操作。

    (2)通过管道进行线程间通信(字节流/字符流)
    (3)join方法的使用

       public static void main(String[] args) {
           try {
               ThreadA thread = new ThreadA();
               thread.start();
               thread.join();
               System.out.println("我在Thread执行完成后,执行了这个log");
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           
       }
       
       private static class ThreadA extends Thread {
           @Override
           public void run() {
               try {
                   int secondValue = (int)(Math.random() * 10000);
                   System.out.println(secondValue);
                   Thread.sleep(secondValue);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
       }
    

    join 会释放锁,sleep 内部用的是sychronized,所以sleep不会释放锁。

    (3)ThreadLocal 相关内容
    ThreadLocal解决的是每个线程绑定自己的值,就想一个线程安全的盒子保存这线程的数据。
    InheritableThreadLocal 可以在子线程中取得副线程传承下来的值。InheritableThreadLocal是ThreadLocal的子类。

    4、Lock的使用

    ReentrantLock类从jdk1.5开始进行支持。除了可以实现synchronized的的同步锁功能外,还可以实现嗅探锁定、多路分支通知等功能。

    (1)基本使用

    private Lock lock = new ReentrantLock();
    try {
      lock.lock();
      .............
    } catch(InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
    

    (2)Condition实现等待/通知
    Object类中的wait()相当于Condition中的await();
    Object类中的wait(long timeout)相当于Condition中的await(long time, TimeUnit unit);
    Object类中的notify()相当于Condition中的signal();
    Object类中的notifyAll()相当于Condition中的signalAll();

    public static void main(String[] args) throws InterruptedException {
            // TODO Auto-generated method stub
            MyService myService = new MyService();
            ThreadA threadA = new ThreadA(myService);
            threadA.start();
            Thread.sleep(3000);
            myService.signal();
        }
        
        private static class MyService {
            
            private Lock lock = new ReentrantLock();
            private Condition condition = lock.newCondition();
            
            public void await() {
                try {
                    lock.lock();
                    System.out.println("await 时间为" + System.currentTimeMillis());
                    condition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
            
            public void signal() {
                try {
                    lock.lock();
                    System.out.println("signal 时间为" + System.currentTimeMillis());
                    condition.signal();
                } finally {
                    lock.unlock();
                }
            }
        }
        
        private static class ThreadA extends Thread {
            
            private MyService myService;
            
            public ThreadA(MyService myService) {
                this.myService = myService;
            }
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                myService.await();
            }
            
        }
    

    (3)公平锁 非公平锁
    公平锁先来先获得锁;非公平锁先来不一定会获得锁,有可能会导致一些线程一直没获得锁。
    Lock lock = new ReentrantLock(boolean isFair);

    (4)各种方法
    getHoldCount()、 getQueueLength()、getWaitQueueLength()
    hasQueueThread()、hasQueueThreads()、hasWaiters()
    isFair()、isHeldByCurrentThread()、isLocked()
    lockInterruptibly()、tryLock()、tryLock(long timeout, TimeUnit unit)
    awaitUninterruptibly()、awaitUntil()

    (5)ReentrantReadWriteLock读写锁
    有两个锁,一个读锁,一个写锁
    多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥

    O了。

    相关文章

      网友评论

        本文标题:《java多线程编程核心技术》读书笔记

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