黑马程序员——多线程篇

来源:互联网 发布:美工培训班学费多少 编辑:程序博客网 时间:2024/06/06 09:31
------- android培训、java培训、期待与您交流! ----------

进程与线程

    学习多线程,首先要知道什么是进程,什么是线程

    ①.进程:进程是一个执行的程序,指的是从代码加载、执行到执行结束的一个完整的过程。

    ②.多进程:计算机同时运行两个或者更多的程序。

    ③.线程:线程是比进程小的执行单位,一个进程可以通过运行多个线程来并发执行多项任务。

    ④.多线程在单个程序中同时运行多个线程来完成不同的工作。

多线程概述

    ①.多线程是实现并发的一种有效手段,一个进程可以通过运行多个线程来并发地执行多项任务,而多个线程之间的调度执行,有系统来决定。

    ②.多个线程可以共享代码段、数据段和诸如打开的文件等的系统资源。

多线程的好处

    ①.线程共享相同的地址空间,提高CPU使用率。

    ②.线程共同分享同一个进程,提高应用程序的使用率。

    ③.由于同一个进程内的线程共享内存和文件,所以线程之间相互通信不必调用内核。

多线程的实现方式

    Java的多线程机制提供了两种方式实现多线程变成,一种是通过继承Thread类来实现,一种是通过实现Runnable接口实现。

1.继承Thread类

    ①.重载该类的run()方法,把需要使用多线程运行的代码放入该方法。

    ②.创建线程对象并用该对象调用start()方法。

public class MyThread extends Thread {@Overridepublic void run() {for (int x = 0; x < 200; x++) {System.out.println(x);}}}

2.实现runnable接口

    ①.实现run()方法,把需要使用多线程运行的代码放入该方法。

    ②.runnable中只有一个run()方法,没有提供任何东西来支持多线程,所以它必须通过Thread类的框架实现多线程。

    ③.通过Thread类的构造函数,public Thread(Runnable target)来实现。

public class MyRunnable implements Runnable {@Overridepublic void run() {for (int x = 0; x < 100; x++) {// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用System.out.println(Thread.currentThread().getName() + ":" + x);}}}

3.为什么定义这两种方式实现多线程

    Java不支持多继承,所以如果用户的类已经继承了一个类,而有需要多线程机制的支持,此时继承Thread类就不现实了。所以Runnable接口在这种情况下就很实用。

4.run()与start()的区别

    ①.run(),仅仅封装了代码,直接调用为普通方法。

    ②.start(),会初始化一些和线程有关的资源,而后会调用run()方法。

线程的调度和优先级

1.线程的调度

    ①.分时调度

    ②.抢占式调度(Java采用的就是该调度模式)

2.线程的优先级

    ①.默认优先级是5

    ②.优先级的范围是0—10。可通过getPriority()方法来获取线程的优先级,通过setPriority()来设置线程的优先级。

线程的常用方法

    ①.void start()     使该线程开始执行;Java 虚拟机调用该线程的 run 方法

    ②.String getName()     返回该线程的名称。 

    ③.void setName(String name)       改变线程名称,使之与参数 name 相同。 

线程的控制

    ①.void interrupt()   中断线程。

    ②.void join()    等待该线程终止。

    ③.void setDaemon(boolean on)    将该线程标记为守护线程或用户线程。 

    ④.static void sleep(long millis)    在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。 

    ⑤.static void yield()    暂停当前正在执行的线程对象,并执行其他线程。 

线程的生命周期

    

多线程的安全问题

1.判断依据

    ①.是否有多线程环境

    ②.是否有共享数据

    ③.是否有多条语句操作共享数据

2.解决的思想

    把多条语句操作共享数据的代码给包成一个整体,让某个线程在执行的时候,别人不能执行。

线程的同步

1.同步的定义

    ①.所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其他线程也不同调用这个方法。

    ②.同步解决的是共享资源冲突的问题。

2.同步的用法

    ①.Java语言提供两个基本的同步用法:同步方法和同步语句(同步代码块)。

    

线程的死锁问题

    死锁问题出现在同步嵌套中,线程不结束就不会释放锁,出现相互等待的情况。

public class DieLock extends Thread {private boolean flag;public DieLock(boolean flag) {this.flag = flag;}@Overridepublic void run() {if (flag) {synchronized (MyLock.objA) {System.out.println("if objA");synchronized (MyLock.objB) {System.out.println("if objB");}}} else {synchronized (MyLock.objB) {System.out.println("else objB");synchronized (MyLock.objA) {System.out.println("else objA");}}}}}

线程间通信问题

1.定义

    线程间通信是指不同种类的线程间,对同一种资源操作。

2.方式

    ①.基本方式

    ②.同步机制:不同种类线程都加锁,必须是同一把锁。

    ③.等待唤醒机制(依次执行):加入flag标记,加入wait()方法,加入notify()方法。

    注意:wait()自动释放锁,醒来时原地起步。并且wait()之后不抢执行权。

public class Student {private String name;private int age;private boolean flag; // 默认情况是没有数据,如果是true,说明有数据public synchronized void set(String name, int age) {// 如果有数据,就等待if (this.flag) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 设置数据this.name = name;this.age = age;// 修改标记this.flag = true;this.notify();}public synchronized void get() {// 如果没有数据,就等待if (!this.flag) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 获取数据System.out.println(this.name + "---" + this.age);// 修改标记this.flag = false;this.notify();}}

0 0
原创粉丝点击