目录
1.notify()和notifyAll()的异同
2.sleep()和wait()的异同
3.什么是死锁?
4.volatile是什么?
5.start()方法和run()方法的区别
6.为什么wait、notify、notifyAll只能调用在Object类中?
7.为什么wait、notify、notifyAll只能在同步方法或同步代码块中使用?
8.Interrupted和isInterruptted方法的区别
9.synchronized和Lock的异同
相同点
不同点
synchronized
Lock
10.如何保证多个线程顺序执行?
相同点:notify()和notifyAll()都可以用来唤醒使用wait进入阻塞状态的线程
不同点:
1.notify()会唤醒一个被wait的线程,若有多个线程被wait,则唤醒优先级最高的一个
notifyAll()会唤醒所有被wait的线程
2.notify()可能导致死锁;notifyAll()不会导致死锁
相同点:都会使得当前线程进入阻塞状态
不同点:
1.sleep()到时间后会主动进入就绪状态,wait必须等待notify()唤醒
2.方法声明的位置不同:thread类中声明sleep();object类中声明wait()
3.调用的要求不同:sleep()方法可以在任何需要的场景下调用,wait必须使用在同步代码块或者同步方法中
4.是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会主动释放锁
死锁:不同的线程分别占用对方的需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,形成了线程的死锁
1.volatile:用来修饰共享变量
2.作用:
保证了不同线程对这个变量的可见性:当一个线程修改了每个变量的值时,新值对其他线程是立即可见的,volatile关键字会强制将修改的值立即写入内存。
禁止进行指令重排序:程序执行到被volatile修饰的变量时,前面的操作的更改肯定全部已经执行,且执行结果对后面的操作可见。
start():用来启动新线程,且start()内部调用了run()方法
run():调用run()方法时,只是在原来的线程中调用,没有开启新线程
因为Java提供的锁是针对对象而言的。以wait方法举例,每个对象存在锁,线程需要等待某些锁时调用对象的wait()方法才有意义。若wait方法定义在Thread类中,线程需要等待的锁就不明显了。由于这三者都是锁级别的操作,定义在Object类中就是因为锁是对象级别的。
因为只有当前线程拥有了某个对象的独占锁时才可以调用对象的wait、notify、notifyAll方法,否则会抛出IlegalMonitorStateException;而线程必须在同步方法或同步代码块中才能得到该对象的同步监视器-锁。
interrupted:使用该方法中断一个线程,就会设置中断状态标识为true,且中断状态会被清零。
isInterruptted:使用该方法用来查询其他线程的中断状态,不会改变中断状态标识。
二者都是通过加锁方式同步解决线程安全问题
都是阻塞式同步
1.执行完同步代码后,会自动释放同步监视器
2.是Java中的关键字,需要jvm来实现
1.需要手动的启动,也需要手动关闭
2.是jdk5.0提供的API,需要lock()和unlock()方法配合try-finnaly实现
使用线程类的join()方法;
join()方法:能够在一个线程中启动另一个线程,另一个线程完成后该方法才开始执行。