---------------------- android培训、java培训、期待与您交流! ----------------------
线程间通信
线程间通信:其实就是多个线程都在操作同一资源,但是操作的动作不同。
线程间通信-等待唤醒机制
线程运行的时候,会在内存中建立一个线程池,等待中的线程都会被临时存放在线程池中,只有被notify()方法唤醒之后,才会被重新CPU所执行。wait()方法、notify()方法和notifyAll()方法并不是定义在Thread类中,而是定义在Object()类中。因为这三个方法都应用在同步机制中,而在同步机制中,都必须要标示出调用这三个方法所属的线程的监视器,然而监视器有可能是任意对象,有可能是实例对象,也有可能是类的字节码对象,所以,可以被任意对象调用的方法都必须定义在Object类中。
JDK1.5中提供了多线程升级解决方案,将同步的synchronized关键字替换成现实的Lock对象操作,将object中的wait(),notify(),notifyAll()方法替换成了Condition类中的await(),signal(),signalAll()方法,Condition对象可以由Lock对象进行获取,实现了本方线程只唤醒对方线程的操作。
Condition将Object监视器方法(wait()、notify()、notifyAll())分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set。其中,Lock替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用。
Condition实例实际上被绑定到一个监视器上。要为特定Lock实例获得Condition实例,必须调用newCondition()方法。
停止线程
如何让线程停止?由于stop()方法已经过时(java虚拟机不在识别该方法),所以只有一种方法,就是让run()方法结束。因为调用start()方法开启多线程,run()方法中的代码通常是循环结构,所以只要控制住循环结构,就可以让run()方法结束,也就是线程结束。
特殊情况,当线程处于冻结状态时,就不会去判断标记,那么线程就不会结束而一直处于冻结状态。此时应该怎么处理呢?在Thread类中提供了一个interrupt()方法,调用该方法后,则线程的冻结状态被强制清除,让处于冻结状态的线程重新正常运行。注意,此时还会抛出一个InterruptedException异常。
setDaemon()方法-守护线程
Thread类中还有一些常用的方法,比如setDaemon(boolean on)方法,该方法必须在启动线程前调用,线程调用该方法后,将该线程标记为守护线程或用户线程,当正在运行的方法全是守护线程是,Java虚拟机退出。
那什么是守护线程呢?守护线程也可以叫做后台线程,我们平时看到的线程都可称之为前台线程,后台线程开启后和前台线程共同抢夺CPU执行权,在开启、运行的时候并没有什么区别。而区别在于,当所有的前台线程运行结束后,后台线程也立即跟着结束运行。
什么时候用到守护线程呢?当A线程的运行依赖于B线程时,可以将A线程标记为守护线程。
join()方法
Thread类中还有一个join()方法,当A线程调用这个方法时,就会强制抢夺当前正在运行的B线程的CPU执行权,B线程处于冻结状态。当A线程运行结束之后,B线程再接着运行。
join()方法的特点:当A线程执行到了B线程的join()方法时,那么A线程就会等待,等B线程执行完,A线程才会接着执行。
join()的作用在于用于临时加入线程。
优先级&yield()方法
Thread类中还有其他一些较为常用的方法,比如toString()方法,该方法覆盖了父类中的toString()方法,定义了线程对象特有的字符串表现形式。该方法返回线程的字符串的表现形式,包括线程名称,优先级和线程组。
优先级的概念,优先级共有10个等级,1至10级,可以调用setPriority(intnewPriority)来给某个线程设置优先级,注意,所有的线程包括主线程在内,默认的优先级都是5。
线程组的概念,A线程开启B线程,那么就可以说B线程属于A线程组中的一员。
yield()方法:yield()方法的作用是暂停当前正在执行的线程对象,并执行其他线程。
多线程总结
1.当某些代码需要同时被执行时,就用单独的线程进行封装。
2.sleep()方法和wait()方法的区别:由于sleep()方法是Thread类的方法,因此它不能改变对象的监视器。所以当在一个synchronized方法中调用sleep()时,线程虽然休眠了,但是对象的监视器没有被释放,其他线程仍然无法访问这个对象。而wait()是Object类的方法,该方法会在线程休眠的同时释放掉监视器,其他线程可以访问该对象。
3.一个线程结束的标志是:run()方法结束。
4.一个监视器被释放的标志是:synchronized块或方法结束。
5.wait()方法和notify()方法:当一个线程执行到wait()方法时,它就进入到一个和该对象相关的线程池中,同时失去了对象的监视器。当它被一个notify()方法唤醒时,线程池中的线程就被放到了就绪队列中。该线程如果获得监视器,就会回到wait()前的中断现场。
---------------------- android培训、java培训、期待与您交流! ----------------------