java多线程编程核心技术-笔记

时间:2024-06-29 15:38:14

一、第一章

1、自定义线程类中实例变量针对其他线程有共享和不共享之分,自定义线程中的变量,如果是继承自thread类,则每个线程中的示例变量的更改,不影响其他线程
2、当多个线程去访问一个局部变量是会产生 非线程安全的问题,需要加synchronize 关键字
3、isAlive() 方法,判断当前的线程是否处于活动状态,已启动,且未终止。
4、sleep() 方法,在指定的毫秒数内,让当前正在执行的线程休眠,但不释放锁
5、停止,中断一个线程,可用stop(已废弃),推荐用interrupted() isInterrupted() 用来判断线程是否终止
6、suspend() 暂停一个线程 需要用resume() 方法来恢复线程的执行,不过该方法已经不鼓励使用
7、线程的优先级分为 1~10 这10 个级别,如果小于1 或者大于10 则抛出异常,setPriority(n) ,n 代表优先级别,数字越大,优先级越高。

二、第二章

1、非线程安全的问题存在于实例变量中,方法内部的私有变量,是不存在非线程安全问题的
2、实例变量中的非线程安全问题,可以通过添加synchronized 关键字来解决,使得多个线程顺序执行
3、关键字synchronized 取得的锁都是对象锁,而不是一段代码或者方法当作锁,哪个线程先执行带有该关键字的方法,哪个线程就持有该方法所属对象的锁Lock
4、只有共享资源的读写访问才需要同步化,如果不是共享资源,根本没有同步的必要
5、关键字synchronized 拥有锁重入功能,也就是在使用该关键字时,当一个线程得到一个对象锁后,再次请求此对象锁 时,是可以得到该对象的锁的,也就是说一个synchronized方法或者块的内部调用本类的其他synchronized方法或者块时,是永远可以得到锁的。
6、synchronized 关键字修饰的方法是对当前对象进行加锁,而synchronized代码块是对某一个对象进行加锁

7、同步代码块 synchronized(this){} 代码块也是锁定的当前对象
8、互斥的代码需要放在synchronized修饰的代码块中,synchronized(obj){} 根据互斥的obj的不同,将互斥分为不同的互斥组。
9、要用到的共同数据包括同步锁或者共同算法的若干个方法应该归类到同一个类中,体检高内聚和程序的健壮性
10、volatile 关键字的作用是强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。读取原子性,更新不是原子性,会有线程安全的问题。

11、Callable跟Runnable类似,可以配合线程池来使用,Callable的call 方法 可以有返回值,通过Future的get()方法来获取,也可以提交一组任务,然后通过,CompletionService.take().get()方法来获取
12、显示锁Lock 实现类为ReentrantLock, 和关键字synchronizd 功能一致,通过lock()方法来实现同步的控制,通过unlock()方法来释放锁
13、读写锁 ReadWriteLock ,多个读锁不互斥,读锁和写锁互斥,写锁和写锁互斥
实现类为ReentrantReadWriteLock 用法
newReentrantReadWriteLock().readLock().lock();
newReentrantReadWriteLock().readLock().unlock();
newReentrantReadWriteLock().writeLock().lock();
newReentrantReadWriteLock().writeLock().unlock();
14、Condition 可以用来替代wait()和notify()方法,必须跟ReentrantLock一起使用
用法:
Lock lock=ReentrantLock();
Condition condition=lock.newCondition();
condition.await(); //等价于wait()方法
condition.signal();//等价于notify()方法
15、semaphore 信号量,控制并发数,也就是控制同时访问资源的线程个数
用法:
Semaphore sem=new Semphore(3);//三个并发数
sem.acquire();//获取信号量
sem.release();//释放信号量
sem.availablePermits();//返回可以使用的信号量数
16、CyclicBarrier 一组线程全部等待彼此达到共同屏障点,当给定数量的线程(线程)正在等待时,它将跳闸,用法:
CyclicBarrier cb =new CyclicBarrier(3);
cb.await();
cb.await();
cb.await();
当有三个 cb.await()时,将进行下一步计划。
17、CountDownLatch 倒计时器,当计数器值减为0 时,等待的现象横将执行下一步操作
通过调用await()方法阻塞,直到由于countDown()方法的调用而导致当前计数达到零,之后所有等待线程被释放,并且任何后续的await() 调用立即返回
CountDownLatch cdl=new CountDownLatch(1);
CountDownLatch cdl2=new CountDownLatch(3);
cdl.await();//等待
cdl2.countDown();//减1
cdl2.countDown();//减1
cdl2.countDown();//减1
cdl.countDown();//减1
18、Exchanger 实现两个线程的数据交换
等待另一个线程到达此交换点,然后将给定对象传输给它,接收其对象作为回报。