就是一批线程结束后才能继续做其它事情,怎么实现?
1、使用countdownlatch latch =new countdownlatch(10),
每个线程执行完调用latch.countdown()
最后判断latch.await();
2、使用future和callable一起实现
3、cyclicbarrier这个是一批线程相互等待,然后都执行完了再一起去干其它事
死锁产生的四个条件?
互斥等待:资源在同一时间内只能被一个进程占有
申请与保持:进程在申请其他资源的时候不释放自己占有的资源
不可剥夺:资源不能强制占有!
环路等待:多个进程互相之间请求资源形成环路
如何避免死锁?
加锁顺序(线程按照一定的顺序加锁)
加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
死锁检测
一个可行的做法是释放所有锁,回退,并且等待一段随机的时间后重试。
一个更好的方案是给这些线程设置优先级,让一个(或几个)线程回退,剩下的线程就像没发生死锁一样继续保持着它们需要的锁。如果赋予这些线程的优先级是固定不变的,同一批线程总是会拥有更高优先级,随机设置优先级
synchronized字段的理解?
对synchronized(this)的一些理解(很细致,感谢作者!)
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
volatile有什么用?能否用一句话说明下volatile的应用场景?
Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比sychronized关键字更轻量级的同步机制。
多线程同步方法?
synchronized:同步方法块或代码块,为对象加内置锁,其他线程阻塞!
使用特殊域变量(volatile)实现线程同步
ReentrantLock类是可重入、互斥、实现了Lock接口的锁
ReentrantLock() : 创建一个ReentrantLock实例 lock() : 获得锁 unlock() : 释放锁
ThreadLocal与同步机制
a.ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题
b.前者采用以"空间换时间"的方法,后者采用以"时间换空间"的方式
多个线程怎么实现数据共享?
线程的优先级。用什么方式调用线程。线程池。
synchronize和lock区别?
lock是接口,lock必须手动释放锁,lock可以响应中断,lock获取锁的时候可以获得结果,即是否成功获得锁
synchronize同步实例方法和静态方法的区别
一个是对类加锁,一个是对对象加锁,对象指的是这个类的对象
对类加锁意思是,所有线程同一时间,只能有一个来访问该类的同步方法,
对对象加锁,所有线程同一时间只能有一个来访问对象的这个实力方法,但是多个对象就可以有多个线程同时访问
yield是指当前线程让出cpu的运行时间,来让其他线程来执行,该线程进入就绪状态,不释放锁,只能让优先级比它高的执行,yield之后当前线程有可能直接又进入运行状态
在线程thread1中的函数内加入 run(){thread2.join},那么线程1会等线程2执行完之后再执行join后的内容
threadlocal是线程本地存储,即为每一个线程都存放一个变量的副本,各个线程之间对变量的操作完全独立,底层是一个map来实现的
例如你定义个变量ThreadLocal<Integer> tl = new ThreadLocal<Integer>()
那么多个线程访问tl的时候访问的都是各个线程自己存储的本地副本,就相当于存放到一个map中,用线程id做key,value等于变量的值,然后每次取都是取的各自的变量
samphare信号量。在前面同步的时候,同步代码同时只能有一个线程访问对吧
但是现在假如我的资源有三个,我允许同时有三个线程来对我访问,那你怎么做
这就有了信号量的概念吗,就是指定可以同时访问公共资源的线程数