20165306 第八周学习任务

第八周学习任务

教材学习内容总结

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()方法结束。

例子12_1

本例在主线程中用Thread的子类创建了两个线程,这两个线程分别在命令行窗口输出20句“大象”和“轿车”,主线程在命令行窗口输出15句“主人”。

4.线程调度与优先级

  • 每个Java线程的优先级都在常数1和10之间,即Thread.MIN_PRIORITYThread.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的子类更具有灵活性。

例子12_2

不使用Thread类的子类创建线程,而是使用Thread类创建speakElephant和speakCar线程。

3.目标对象与线程的关系

  • 目标对象和线程完全解耦:目标对象经常需要通过获得线程的名字(因为无法获得线程对象的引用)以便确定被JVM正在执行的线程是哪个。

String name=Thread.currentThread().getName();

例子12_3

  • 目标对象组合线程(弱耦合):目标对象可以通过获得线程对象的引用来确定被JVM正在执行的线程是哪个。

Thread.currentThread();

例子12_4

12.4线程的常用方法

  • isAlive()

    • 线程处于新建状态时,线程调用isAlive()方法返回false
    • 没有进入死亡状态之前,返回true
    • 进入死亡状态后(实体内存被释放),返回false

注意:一个已经运行的线程在没有进入死亡状态时,不要再给线程分配实体,由于线程只能引用最后分配的实体,先前的实体就会成为“垃圾”,并且不会被垃圾收集器收集掉。

例子12_5

  • currentThread():可以用类名调用,该方法返回当前正在使用CPU资源的线程。

  • interrupt() :吵醒休眠的线程,即导致休眠的线程发生InterruptedException异常,从而结束休眠,重新排队等待CPU资源。

例子12_6

12.5线程同步

多个线程调用synchronized方法必须遵守同步机制。

线程同步机制:当一个线程A使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到线程A使用完该synchronized方法。

例子12_7

12.6协调同步的线程

wait()、notify()、notifyAll()都是Object类中的final方法,被所有的类继承且不允许重写得方法。不可以在非同步方法中使用wait()、notify()、notifyAll()。

例子12_8

教材学习中的问题和解决过程

”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
原文地址:https://www.cnblogs.com/5306xyh/p/8905995.html