继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

幕布斯6054654
关注TA
已关注
手记 1297
粉丝 219
获赞 1011

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


webp

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);



作者:捉影T_T900
链接:https://www.jianshu.com/p/56fec6d44458


打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP