第八周学习任务
教材学习内容总结
12.1进程与线程
1.操作系统与进程
- 程序是一段静态的代码,进程是程序的一次动态执行过程,这个过程也是进程本身从产生、发展至消亡的过程。
- 可以让计算机系统中的多个进程轮流使用CPU资源,甚至可以让多个进程共享操作系统所管理的资源。
2.进程与线程
- 线程不是进程,是比进程更小的执行单位,线程的中断和恢复可以更加节省系统的开销。
- 没有进程就不会有线程,没有操作系统就不会有进程。
12.2Java中的线程
1.Java的多线程机制
- 多线程是指一个应用程序中同时存在几个执行本,按几条不同的执行线索共同工作的情况。
- 计算机在任何给定的时刻只能执行线程中的一个。这些线程被轮流执行,使得每个线程都有机会使用CPU资源。
2.主线程(main线程)
主线程(main线程)负责执行main方法。
3.线程的状态和生命周期
使用Thread类及其子类的对象来表示线程。
-
新建:一个Thread类或其子类的对象被声明并创建,已经有了相应的内存空间和其他资源。
-
运行:JVM将CPU使用权切换给该线程时,此线程就可以脱离创建它的主线程独立开始自己的生命周期了。程序必须在子类中重写父类的run()方法,在线程没有结束run()方法之前,不要让线程再调用start()方法,否则将发生IllegalThreadStateException异常。
-
中断:有四种原因的中断
- JVM将CPU资源从当前线程切换给其他线程,使本线程让出CPU的使用权处于中断状态。
- 线程使用CPU资源期间,执行了sleep(int millsecond)方法,使当前线程进入休眠状态。
- 执行了wait()方法,使得当前线程进入等待状态,必须由其他线程调用notify()方法通知它,使得它重新进到线程队列中排队等待CPU资源。
- 执行某个操作进入阻塞状态,比如执行读/写操作引起阻塞。只有当引起阻塞的原因消除时,线程才重新进到线程队列中排队等待CPU资源。
-
死亡:不具有继续运行的能力。死亡原因之一是执行完run()方法中的全部语句,结束了run()方法;死亡原因之二是强制run()方法结束。
本例在主线程中用Thread的子类创建了两个线程,这两个线程分别在命令行窗口输出20句“大象”和“轿车”,主线程在命令行窗口输出15句“主人”。
4.线程调度与优先级
-
每个Java线程的优先级都在常数1和10之间,即
Thread.MIN_PRIORITY
和Thread.MAX_PRIORITY
之间。如果没有明确地设置线程的优先级别,,每个线程的优先级都为常数5,即Thread.NORM_PRIORITY
。 -
可以通过
setPriority(int grade)方法调整优先级,
getPriority``` 方法返回线程的优先级。 -
当线程使用CPU资源的时间到时后,即使线程没有完成自己的全部操作,JVM也会中断当前线程的执行,把CPU的使用权切换给下一个排队等待的线程,当前线程将等待CPU资源的下一次轮回,然后从中断处继续执行。
12.3Thread类与线程的创建
1.使用Thread的子类
在编写Thread类的子类时,需要重写父类的run()方法。
2.使用Thread类
-
可以在子类中增加新的成员变量和方法,Java不支持多继承,Thread类的子类不能再扩展其他的类。
-
用Thread类直接创建线程对象:``` Thread(Runnable target),该构造方法中的参数是一个Runnable类型的接口。
-
对于使用同一目标对象的线程,目标对象的成员变量自然就是这些线程共享的数据单元,使用Runnable接口比使用Thread的子类更具有灵活性。
不使用Thread类的子类创建线程,而是使用Thread类创建speakElephant和speakCar线程。
3.目标对象与线程的关系
- 目标对象和线程完全解耦:目标对象经常需要通过获得线程的名字(因为无法获得线程对象的引用)以便确定被JVM正在执行的线程是哪个。
String name=Thread.currentThread().getName();
- 目标对象组合线程(弱耦合):目标对象可以通过获得线程对象的引用来确定被JVM正在执行的线程是哪个。
Thread.currentThread();
12.4线程的常用方法
-
isAlive()
- 线程处于新建状态时,线程调用isAlive()方法返回false
- 没有进入死亡状态之前,返回true
- 进入死亡状态后(实体内存被释放),返回false
注意:一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体,由于线程只能引用最后分配的实体,先前的实体就会成为“垃圾”,并且不会被垃圾收集器收集掉。
-
currentThread()
:可以用类名调用,该方法返回当前正在使用CPU资源的线程。 -
interrupt()
:吵醒休眠的线程,即导致休眠的线程发生InterruptedException异常,从而结束休眠,重新排队等待CPU资源。
12.5线程同步
多个线程调用synchronized方法必须遵守同步机制。
线程同步机制:当一个线程A使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到线程A使用完该synchronized方法。
12.6协调同步的线程
wait()、notify()、notifyAll()都是Object类中的final方法,被所有的类继承且不允许重写得方法。不可以在非同步方法中使用wait()、notify()、notifyAll()。
教材学习中的问题和解决过程
”P373当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量。程序应对这样的问题做出处理,否则可能发生混乱。”
-
问题:会出现怎样的混乱?
-
解答:若去掉例子12_7saveOrTake方法的同步修饰synchronized,运行效果如下图:
代码调试中的问题和解决过程
- 问题:编译失败,运行却成功了,如下图:
- 解答:少写了
joinThread.join()
(当前线程开始等待joinThread结束)这行代码
代码托管
上周考试错题总结
- DriverManager管理一组 JDBC 驱动程序的基本服务。DataSource 接口是 JDBC 2.0 API 中的新增内容,它提供了连接到数据源的另一种方法。使用 DataSource 对象是连接到数据源的首选方法。
- D选项错误,JDBC提供了对Java程序员、数据库厂商及第三方中间件厂商的API。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | |
---|---|---|
目标 | 10000行 | 30篇 |
第八周 | 1175/5596 | 2/16 |