多线程知识点记录②

1.多个线程多把锁,锁有分对象锁和类锁,类锁就是在同步函数上加static关键字。
2.两个线程访问一个对象锁的两个加锁方法,要等一个线程释放锁后两个线程才能拿到对象锁进行另一个方法的访问。
3.子类调用父类中的同步方法,线程也是安全的。
4.不要用字符串加锁。
5.把一个对象作为锁,里面的属性值变化是不影响锁的。
6.每开一个线程,每个线程都会有一个本线程的内存空间,在类中用到的成员变量都会装到这个内存中,并且直接引用这个内存中的变量,
所以修改变量时不会修改到这个内存中的值,但是类中还是直接用的这个内存中的值,但是如果变量加volatile时,变量被修改后子线程就会
直接到主线程里取读数据,而不会再去自己的内存中读数据了。
7.加volatile只是有可见性,但是没有原子性,也就是线程是不安全的,如果要保证线程安全可以用automicInteger等api,automic也只是保证
本方法中的同步,多线程之间也是线程不安全的,所以多线程进行访问的话要加synchronized。
8.wait和notify必须配合synchronize使用,wait释放锁,notify不释放锁。因notify不马上释放锁,所以不能做到实时的效果,所以可以使用
Countdownlatch,它相当于wait,notify的升级版。
9.ThreadLocal修饰的参数,不是每个线程公用的,而是每个线程都有自己的一块空间,各不干扰。
10.多线程下的单例可以用静态内部类。
11.同步类容器虽然也是线程安全的,但是效率不高。
12.并发类容器有current接口下的一些实现类,比如currentHashMap,CopyOnWrite,CopyOnWrite在添加元素之前会复制出一个新的容器,元素都
存到新容器下,旧容器用于查询,做到读写分离了。CopyOnWrite在读多写少的情景下用的多。
13.队列有分无堵塞队列和堵塞队列,无堵塞队列是concurrentLinkedQueue,堵塞队列有ArrayBlockingQueue--数值结构,有界队列,LinkedBlockingQueue
--链表结构,无界队列,synchronizeQueue,队列大小为空,只有在有请求堵塞的情况下,添加才会成功,添加不是直接添加到队列中,而是直接赋给
正在请求的堵塞线程。PriorityBlockingQueue,存到队列中的对象都必须实现comparable接口,是一个无界队列,DelayBlockingQueue,存到队列中的对象都
必须实现Delayed接口,延迟时间到才能从队列中取出对象。
14.线程池有分FixedThreadPool--固定大小线程池,CachedThreadPool--缓冲线程池,线程池中的队列无界,可以一直添加任务,初始化核心
线程数为0,队列是一个synchronizeQueue队列。SingleThreadExcutor--只有一个线程,队列是无界队列,ScheduledThreadPool,定时线程池,
类似Timer,线程中的线程都是一个定时任务,scheduleWithFixedDelay和scheduleAtFixedRate的区别是前者无论执行时间是否大于还是小于定时时间,
都要延迟到指定的间隔时间再执行,后者是如果执行时间大于间隔时间,当前任务执行则马上进入下一个循环任务。线程池submit和execute的区别一个是submit有返回值。
另一个是submit可以接收到异常。第三个是传递的参数不一样,submit可以接收实现Callable接口的线程任务。
15.Java容器总结,linked是链表结构,增删快,查询慢,tree是二叉树结构,有序的,hash是hash表结构,是唯一性,不可重复的,array是数组结构的,查询快,增删慢。
除了vector是线程同步的,其他都是不同步的,但是可以通过collections集合工具类进行同步转换。collection和map接口,collction下有两个set和list接口,
set下有实现类:haseset和treeset,linkedhashset,list下有arraylist和linkedlist,map下有treemap和hashmap,linkedhashmap。
16.concurrent接口下的一些工具类:countDownLatch-->因为notify没有马上释放锁,所以需要的马上释放锁的业务场景下不能满足,因此可以使用CountDownLatch.await,
CountDownLatch.countDown进行释放。
17.实现Callable接口是为了条用threadPool.submit可以返回数据。
18. add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
offer 添加一个元素并返回true 如果队列已满,则返回false
put 添加一个元素 如果队列已满,则阻塞

take 移除并返回队列头部的元素 如果队列为空,则阻塞
remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
poll 移除并返问队列头部的元素 如果队列为空,则返回null

element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常
peek 返回队列头部的元素 如果队列为空,则返回null

19.用户线程和守护线程的区别:当还有用户线程在运行时,jvm不能关闭,不管是否有守护线程,jvm都可以关闭,像垃圾回收的线程就是守护线程。
20.获取到锁,但是没有执行权(就是cpu还没切换过来),当前的状态是就绪状态,join,sleep完后就是进入就绪状态,因为他们都是释放执行权,但是没有释放锁,yield虽然
也是释放执行权,没释放锁,但是yield是直接进入就绪状态。
21.interrupt和stop的区别是interrupt在运行状态不会马上停止线程,而且会有异常可以捕获。并且关掉该关掉的所有资源,然后再进行强制中断。
22.线程状态:新建,就绪,运行,(堵塞,等待,睡眠),死亡。
23.yield:如果你觉得一个线程不是那么重要,或者优先级非常低,而且又害怕它会占用太多的CPU资源,那么可以在适当的时候调用Thread.yield(),
给予其他重要线程更多的工作机会。线程调用该方法后会把执行权让给相同优先级的其他线程。
24.isDaemon是否是守护线程,true为是。
25.setPriority设置优先级(1到10)。
26.CountDownLatch和CyclicBarrier的区别:
CountDownLatch : 一个线程(或者多个),等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier: N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待,而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。
而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。
27.callable和runnable都是线程实现的接口,callable的方法是call,runnable是run,callable有返回值并且可以捕获异常。
28.shutdown和shutdownNow都是停止线程池的新任务提交,区别是shutdown会等线程池中的任务和正在运行的线程运行完才会。而shutdownNow则会清空线程池中的任务,并且
尝试用interrupt中断所有正在执行的线程。
29.线程stop和interrupt的区别是stop强制中断线程,现在已经不提倡用这个,而interrupt是会先把该关的资源先关掉,在进行中断。
30.信号量semaphore,主要防止一些重要代码被N个线程进入。主要方法是acquire和release。
31.交换器exchanger,两个线程之间的数据交换,只能是两个线程,要两个线程都执行exchanger.exchange()才会进行数据交换。

原文地址:https://www.cnblogs.com/3chi/p/8423258.html