线程的yield()方法和sleep()方法有什么不同?
1.sleep()方法会使当前线程暂停指定的时间,不会消耗cpu的时间片。
2.调用sleep()方法会使当前线程进入阻塞状态,而yield()方法只是给cpu一个提示,如果cpu接收到这个提示,就会去执行相应的方法。
3.sleep()方法一定能完成给定的时间,而yield方法不一定。
4.sleep()方法需要抛出InterruptedException异常,而yield()不用抛出这个异常。
sleep()方法和wait()方法的区别?
相同点:
1.wait()方法和sleep()方法都可以使线程进入阻塞状态。
2.wait()方法和sleep()方法都是可中断方法,被中断后都会收到中断异常。
不同点:
1.wait()是object类的方法,sleep()是thread类的方法。
2.wait()方法必须在同步方法中执行,sleep()方法不需要。
3.线程在同步方法中执行sleep()方法不需要释放monitor锁,而wait()方法会释放monitor的锁。
4.sleep()在短暂的休眠之后会自动退出阻塞状态,而wait()方法执行完之后不会自动退出阻塞状态,需要其他线程中断才能退出阻塞状态。
线程同步的方法有哪些?
1.锁和同步。
2.管道。
3.信号量。
4.wait()/notify()。
为什么wait(),notify(),notifyAll()方法被定义在Object类中而不是Thread类中?
1.因为这些方法在操作同步线程时,都需要标识他们操作线程的锁,只有同一锁上的被等待线程,才能被同一把锁上的notify()或者notifyAll()方法唤醒,不可以被不同锁的notify或notifyAll()方法唤醒,也就是说等待和唤醒必须是同一对象。而锁可以是任意对象,所以就算object类了。
为什么wait(),notify(),notifyAll()都需要在同步代码块或者同步方法中被调用?
因为wait()暂停的是持有锁的对象,notify()和notifyAll()唤醒的是等待锁的对象,wait(),notify(),notifyAll()都需要持有锁的对象,进而需要在同步代码块或者同步方法中被调用。
为什么Thread类的sleep()方法和yield()方法是静态的?
因为sleep()方法和yield()方法都是需要正在执行的线程调用的,对于那些阻塞的或者等待的线程调用这两个方法是毫无意义的。
如何唤醒一个阻塞的线程?
如果线程是由于wait(),sleep(),yield(),join()方法引起的阻塞就可以被唤醒,如果线程是由于IO阻塞引起的,是无法进行唤醒的,因为IO是操作系统层面的,java代码无法直接触及操作系统。
1.wait():可使用notify()或者notifyAll()方法唤醒。
2.sleep():调用该方法可以使线程在指定的时间内阻塞,等到时间过去了,就退出阻塞状态。
3.yield():使当前线程放弃时间片,但是仍有可能再次获得时间片,退出阻塞状态。
4.join():线程A调用线程B的join()方法,使得线程A进入阻塞状态,直到线程B运行完成,线程A才由阻塞状态转为可执行状态。
什么是线程互斥?什么是线程同步?他们是如何实现的?
线程互斥指的是每次都保证只有一个线程访问一个资源,具有排他性和唯一性,但是不保证访问的顺序性。
线程同步指的是在互斥的基础上保证对线程的访问是顺序的。
线程同步:
1.同步方法
2.同步代码块。
3.wait()和notify()方法。
4.使用可重入锁实现。
5.使用volatile实现。
6.使用阻塞队列实现。
在java程序中如何保证线程的运行安全?
线程的安全主要体现在 原子性,可见性和有序性。
原子性:一个或者多个操作在cpu执行的过程中不被中断的过程。线程切换带来的原子性问题。
可见性:一个线程对共享变量的修改,能够立刻被另一个线程看到。缓存带来的可见性问题。
有序性:程序的执行按照代码的先后顺序执行。编译优化带来的有序性问题。
解决方法:
1.原子性:可以使用jdk中的原子类,synchronized,lock来解决。
2.可见性:使用volatile解决。
3.有序性:使用happens-before规则来解决。