教材学习内容总结
1.
进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。
线程是比进程更小的执行单位,每个线程也有它自身的产生、存在和消亡的过程。
线程的中断与恢复可以更加节省系统的开销。
2.
多线程是指一个应用程序中同时存在几个执行体,按几条不同的执行线索共同工作的情况,它使得编程人员可以很方便地开发出具有多线程功能、能同时处理多个任务的功能强大的应用程序
3.
当JVM加载代码,发现main方法之后,就会启动一个线程,这个线程称为“主线程”(main线程),该线程负责执行main方法。
如果main方法中没有创建其他的线程,当main方法返回时,JVM就会结束我们的Java应用程序。
如果main方法中又创建了其他线程,main方法即使执行完最后的语句(主线程结束),JVM也不会结束Java应用程序,JVM一直要等到Java应用程序中的所有线程都结束之后,才结束Java应用程序。
4.
使用Thread类及其子类的对象来表示线程。
线程创建后仅仅仅是占有了内存资源,在JVM管理的线程中还没有这个线程,此线程必须调用start()方法(从父类继承的方法)通知JVM,这样JCM就会知道又有一个新线程排队等候切换了。
如果线程是Thread的子类创建的,该类中的run()方法就立刻执行,run()方法规定了该线程的具体使命。
Thread类中的run()方法没有具体内容,程序要在Thread类的子类中重写run()方法来覆盖父类的run()方法。
5.
执行sleep(int millsecond)方法,使当前线程进入休眠状态。经过参数millsecond指定的毫秒数之后,该线程就重新进到线程队列中排队等候CPU资源。
执行wait()方法,使得当前线程进入等待状态。等待状态的线程不会主动进到线程队列中排队等待CPU资源,必须由其他线程调用notify()方法通知它,使得它重新进到线程队列中排队等待CPU资源。
6.
线程死亡的原因有二,一个是正常运行的线程完成了它的全部工作,即执行完run()方法中的全部语句,结束了run()方法;另一个原因是线程被提前强制性地终止,即强制run()方法结束。
7.
每个java线程的优先级都在常数1和10之间,即Thread.MIN_PRIORITY和Thread.MAX_PRIORITY。如果没有明确地设置线程的优先级别,每个线程的优先级都为常数5,即Thread.NORM_PRIORITY。
优先级可以通过setPriority(int grade)方法调整。getPriority方法返回线程的优先级。
如果有A、B、C、D四个线程,A和B的级别高于C和D,那么,Java调度器首先以轮流的方式执行A和B,一直等到A、B都执行完毕进入死亡状态,才会在C、D之前轮流切换。
8.
使用Thread子类创建线程的优点是:可以在子类中增加新的成员变量,使线程具有某种属性,也可以在子类中新增加方法,使线程具有某种功能。
使用Thread创建线程通常使用的构造方法是:Thread(Runnable target)。
对于使用同一目标对象的线程,目标对象的成员变量自然就是这些线程共享的数据单元。
9.
在线程没有结束run()方法之前,不赞成让线程再调用start()方法,否则将发生IllegalThreadStateException异常。
必须在try-catch语句块中调用sleep方法。
线程处于新建状态时,线程调用isAlive()方法放回false。当一个线程调用start()方法,并占用CPU资源后,该线程的run()方法就开始运行,在线程的run()结束之前,即没有进入死亡状态之前,线程调用isAlive()方法放回true。
一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体,由于线程只能引用最后分配的实体,先前的实体就会称为“垃圾”,并且不会被垃圾收集器收集掉。
currentThread()方法是Thread类中的类方法,可以用类名调用,该方法返回当前正在使用CPU资源的线程。
当一些线程调用sleep方法处于休眠状态时,一个占有CPU资源的线程可以让休眠的线程调用interrupt()方法“吵醒”自己,即导致休眠的线程发生InterruptedException异常,从而结束休眠,重新排队等待CPU资源。
10.
线程同步就是若干个线程都需要使用一个synchronized(同步)修饰的方法,即程序中的若干个线程都需要使用一个方法,而这个方法用synchronized给予了修饰。
线程同步机制:当一个线程A使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到线程A使用完该synchronized方法。
11.
当一个线程使用的同步方法中用到某个变量,而此变量又需要其他线程修改后才能符合本线程的需要,那么可以在同步方法中使用wait()方法。
用notifyAll()方法通知所有由于使用这个同步方法而处于等待的线程结束等待,曾中断的线程就会从刚才的中断处继续执行这个同步方法,并遵循“先中断先继续”的原则。
用notify()方法,只是通知处于等待中的线程的某一个结束等待。
不可以在非同步方法中使用wait(),notify(),notifyAll()。
12.
一个线程A在占有CPU资源期间,可以让其他线程调用join()和本线程联合。
如果线程A在占有CPU资源期间一旦联合B线程,那么A线程将立即中断执行,一直等它联合的线程B执行完毕,A线程再重新排队等待CPU资源,以便恢复执行。如果A准备联合的B线程已经结束,那么B.join()不会产生任何效果。
13.
AWT-EventQueue线程负责处理GUI事件,AWT-Windows线程负责将窗体或组件绘制到桌面。
14.
用Timer类的构造方法Timer(int a,Object b)创建一个计时器,其中的参数a的单位是毫秒,确定计时器每个a毫秒“震铃”一次,参数b是计时器的监视器。
当我们想让计时器只震铃一次时,可以让计时器调用setReapeats(boolean b)方法,参数b的值取false即可。
计时器还可以调用setInitialDelay(int depay)设置首次震铃的延时。
用Timer类的方法start()启动计时器,即启动线程。用Timer类的方法stop()停止计时器,即挂起线程,用restart()重新启动计时器,即恢复线程。
计时器的监视器必须是组件类(例如JFrame,JButton等)的子类的实例,否则计时器无法启动。
15.
线程调用void setDaemon(boolean on)方法可以将自己设置成一个守护(Daemon)线程。
当程序中的所有用户线程都已结束运行时,即使守护线程的run方法中还有需要执行的语句,守护线程也立即结束运行。
一个线程必须在运行之前设置自己是否是守护线程。
教材学习中的问题和解决过程
参考资料
《java 2实用教程(第5版)》