判断线程中是否有安全隐患?
1,先明确线程的代码有哪些
2,线程代码中是否有共享数据
3,是否有多条语句操作共享数据
解决方法:
同步解决
同步函数:synchronized 作为修饰词加在函数上。
持的锁是:this
同步函数和同步代码块的区别?
同步函数比同步代码块简单。
同步函数不用刻意定义锁对象,减少了代码的缩进
同步函数用的锁是固定的:就是this。
同步代码块锁是任意的。
相对而言,同步代码块用的多一些。而且锁是指定的,阅读性好一些。
静态同步函数的锁是什么呢?
该类的所属字节码文件对象:类名.Class
类名.class :是一个属性,表示该类所属的字节码文件对象。
懒汉式被多线程并发访问时:
会出现线程安全问题,因为:
1,多个线程共享一个对象。
2,有多条语句操作共享数据。
懒汉式中减少锁的判断次数:
多一层判段。
面试:懒汉式,并发访问?,提高效率?。
class SingleDemo{
private static SingleDemo sg;
private SingleDemo(){}
public static SingleDemo getInstance(){
if(sg!=null){
synchronized(SingleDemo.class) {
if(sg!=null){
sg = newSingleDemo();
}
}
}
return sg;
}
}
线程间通信:
多个线程处理同一个资源,但是处理的动作却一样。
常用的机制是等待唤醒机制。
wait():将运行的线程置于冻结状态,释放了执行权和执行资格,并将等待的线程存储
到了线程池。
notify():
对线程池中的等待线程进行唤醒,让线程恢复到运行状态,
或者恢复到临时阻塞状态。其实就是让等待的线程再次具备执行资格。
注意:一次只唤醒一个,而且随机的。
notifyAll():
唤醒线程池中所有的等待线程。
wait notifynotifyAll方法都用在同步中。
必须标示出是作用在哪个同步的锁上。
用法:锁.wait 锁.notify 锁.notifyAll();
java.util.concurrent.locks
Lock接口
在jdk1.5中提供了Lock对象。
lock();获取锁
unlock();释放锁
newCondition():获取与锁相结合的Condition对象。
Condition:
await
signal
signalAll
在jdk1.5中提供了Lock对象替代了synchronized
Lock接口中提供了获取锁lock(),释放锁unlock();
同步使用的隐士的获取锁和释放锁动作。
而升级后,将获取锁和释放锁变成显示的。
以前同步中用于操作锁的方法 wait notify notifyAll,
也被jdk1.5中的对象替代了,替代对象是Condition,将操作的锁的方法单独从Object中封装到了Condition对象中。
早期同步中的锁用的Object中的操作方waitnotify notifyAll。
升级后。
同步锁被Lock替代变成了指定锁。Object中方法也被Condition封装替代,替代方法是Condition对象的中awaitsignal signalAll。
那么升级后,在对锁操作,就必须让Lock和Condition相结合.
如何将Lock和Condition结合呢?
可以通过Lock接口中的newCondition()来获取和该锁对象相结合的Condition操作的锁的方法
新升级的内容Lock Condition的好处:
一个Lock可以绑定多个 用于操作锁的方法对象。 Lock上可以有多个Condition。这样就解决了
多生产者和多消费者以前用notifyAll唤醒全部,导致本方被唤醒效率低的问题。
给生产者分配一个Condition,给消费者分配另一个Condition。
可以实现,生产者中唤醒消费者,而不在唤醒本方
停止线程:
如何停止:结束run方法,即结束循环,结束循环一般是判断或修改标记。
当线程中存在冻结线程的语句时,读不到修改标记的语句。需要用到interrupt来强制中断线程的冻结状态。
interrupt:
强制中断线程的冻结状态,让线程变成运行或临时阻塞状态。不抛出interruptedExceptio异常。
setDaemon(Boolean):
将线程设置为守护线程,需要在开启线程之前设置;
守护线程可以简单理解为后台线程;
当前台线程都结束时,后台线程自动结束;
当线程都变成守护线程时,进程结束。
join:
当执行线程(A)执行到某一个线程(B)时,该线程(A)会释放执行权和执行资格处于冻结状态。
此时某一个线程(B)会被执行,而执行线程(A)必须等到某一个线程(B)执行完毕后,该执行线程才可以被执行。
何时用join方法:
当在执行过程中,需要临时加入一个线程进行运算,可以使用join方法。
toString:
Thread.currentThread().toString()
返回当前线程的名字、优先级、所属的线程组。
setPrivority:
设置线程优先级。1—10;数值越大优先级越高。
MAX_PRIORITY 10
MIN_PRIORITY 1
NORM_PRIORITY 5
yield():
暂停当前线程并执行其他线程。