最近读完了《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);
作者:捉影T_T900
链接:https://www.jianshu.com/p/56fec6d44458
共同学习,写下你的评论
评论加载中...
作者其他优质文章