黑马程序员_多线程


------- android培训java培训、期待与您交流! ----------


多线程:

1 进程:就是正在运行的程序,也就是代表程序所占用的内存区域。

线程:线程代表程序的执行路径,执行单元。

如果一个应用程序的执行只有一个执行路径,就称为单线程程序;

如果一个应用程序的执行有多条窒息那个路径,就称为多线程程序。

例如:迅雷下载,360安全卫士等。

思考:Jvm的启动是多线程的,还是单线程的?

Jvm在启动时,最少启动了main线程和垃圾回收线程。因为如果只启动main线程的话,那么随着程序的执行,可能会引发内存溢出,所以垃圾回收线程必须一直在运行,所以它是一个多线程的。

查API:java.lang.Thread线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。 其实在同一个时刻,只能有一个应用程序在执行。CPU在每一个应用程序间进行着高效的切换。

2 实现多线程的方法:

实现多线程可以通过继承Thread类和实现Runnable接口。

(1)继承Thread

    1.创建一个类继承Thread类;

2.子类复写父类中的run方法,将线程运行的代码存放在run中;

因为run方法里面封装了多线程要执行的代码.

  3.通过调用start方法开启线程而不是调用run方法。

4.常见方法:getName( ),Thread.currentThread( );        

(2)实现Runnable接口;

1.创建Runnable类的实现类,子类复写接口中的run方法;

2.通过Thread类创建线程,并将事先了Runnable接口的子类对象作为参数传递给Thread类的构造函数。

3.Thread类对象调用start方法开启线程,因为Runnable类以及其实现类没有start方法。

两种方法区别:

(1)实现Runnable接口避免了单继承的局限性

(2)继承Thread类线程代码存放在Thread子类的run方法中

   实现Runnable接口线程代码存放在接口的子类的run方法中;

   在定义线程时,建议使用实现Runnable接口,因为它可以避免单继承,能实现该接口的同时还能继承或实现其他类或接口。

思考1:为什么要给Thread类的构造函数传递Runnable的子类对象?

Thread类中有一个Runnable类型的成员变量来接收Runnable的子类对象,并且在Thread方法开启线程是会运行该对象里面的run方法,这样就相等于把需要多线程运行的任务作为参数进行传递了。

思考2start()run()方法的区别?

start()方法是Thread类中的方法,它的作用是启动线程;而run( )方法是Runnable接口中的抽象方法,Thread类实现了该接口并复写了该方法,它用于封装需要被多线程执行的代码。

3、线程的几种状态:

新建:new一个Thread对象或者其子类对象就是创建一个线程,当一个线程对象被创建,但是没有开启,这个时候,是对象线程对象开辟了内存空间和初始化数据。         

就绪:新建的对象调用start方法,就开启了线程,线程就到了就绪状态。 在这个状态的线程对象,具有执行资格,没有执行权。

运行:当线程对象获取到了CPU的资源。在这个状态的线程对象,既有执行资格,也有执行权。

冻结:运行过程中的线程由于某些原因(比如wait,sleep),释放了执行资格和执行权。当然,他们可以回到运行状态。只不过,不是直接回到运行状态而是先回到就绪状态。

死亡:当线程对象调用的run方法结束,或者直接调用stop方法,就让线程对象死亡,在内存中变成了垃圾。

4、线程安全问题

(1)导致安全问题出现的原因:

A.多个线程访问出现延迟;

B.线程随机性。

注:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的。

如何判断一个程序是否有线程安全问题?

A:是否有是操作共享的数据;

B:操作数据的语句是否是多条;

C.是否在多线程程序中;

(2)解决方法:对多条操作共享数据的语句进行同步,一个线程在执行过程中其他线程不可以参与进来

5、同步(synchronized

(1)格式:

Synchronize(对象){需要同步的代码},它可以解决安全问题的根本原因就在那个对象上,该对象如同锁的功能。

(2)前提:

A.同步需要两个或两个以上的线程;

B.多个线程使用的是同一个锁

(3)弊端:

当线程相当多时,每个线程都会取判断同步上的锁,比较耗资源,降低程序的运行效率。

(4)同步的两种表现形式:

A.同步代码块:

定义在方法内,需要使用同一个锁对象。

注意:

虽然同步代码快的锁可以使任何对象,但是在进行多线程通信使用同步代码快时,必须保证同步代码块锁的唯一性,否则会报错。

同步函数的锁是this,也要保证同步函数的锁的对象和调用waitnotifynotifyAll的对象是同一个对象,也就是都是this锁代表的对象。

格式:

synchronized(对象)

{

需同步的代码;

}

(2)同步函数

定义在方法上用synchronized修饰符修饰。

:非静态同步函数的锁为this,而静态同步函数的锁是该方法所在的类的字节码文件对象,即类名.class文件

格式:

修饰词 synchronized 返回值类型 函数名(参数列表)

{

需同步的代码;

}

注意:如果对多个程序加锁了,但是还有问题,那么需要考虑多线程的锁对象是不是同一个。

jdk1.5后,提供了可重入锁对象,用lock锁取代了synchronized

6sleep()wait()的区别:

 (1)这两个方法来自不同的类,sleep()来自Thread类,和wait()来自Object类。

 (2)sleepThread的静态类方法,而wait()Object类的非静态方法

 (3)sleep()释放资源不释放锁,而wait()释放资源释放锁;

 (4)使用范围:wait,notifynotifyAll只能在同步控制方法或者同步控制块里面使用,sleep可以在任何地方使用,但当一个线程正在使用或者更新同一个共享数据,这样容易导致程序出现错误的结果。 

使用等待唤醒机制做一个接力跑的游戏!

6、使用synchronized同步来解决懒汉式单例设计模式的安全问题



7、死锁

两个线程对两个同步对象具有循环依赖时,就会发生死锁。即同步嵌套同步,而锁却不同。

8、wait()sleep()notify()notifyAll()

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。 

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。 

notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程(一般是最先开始等待的线程),而且不是按优先级。 

notityAll():唤醒所有处入等待状态的所有线程.

9、为什么wait()notify()notifyAll()这些用来操作线程的方法定义在Object类中?

(1)这些方法只存在于同步中;

(2)使用这些方法时必须要指定所属的锁;

(3)而锁可以是任意对象,所以任意对象调用的方法就定义在Object中。

10、线程间通信(生产者与消费者)

A.问题:数据错乱。

原因分析:因为等待线程被唤醒后没有判断标记!

解决方法:该if语句为while循环语句,要让被唤醒的线程再一次判断标记;

B.问题:while()语句后,导致程序挂起

原因分析:因为只用notify,容易出现只唤醒本方线程的情况,导致程序中所有线程等待

解决方案:改notify()notifyAll(),唤醒对方线程。

10LockCondition

JDK1.5版本提供了显示的锁机制!!以及显示的锁对象上的等待唤醒操作机制。将同步synchonized替换成了显示的Lock操作,将Object中的waitnotifynotifyAll替换成了Condition对象。“它实现提供比synchronized方法和语句可获得的更广泛的锁的操作,此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象”。该对象可以Lock锁进行获取

Lock的方法摘要:

void lock()  获取锁。 

Condition newCondition() 返回绑定到此 Lock 实例的新 Condition 实例。 

void unlock() 释放锁。

Condition方法摘要:

void await() 造成当前线程在接到信号或被中断之前一直处于等待状态。

void signal() 唤醒一个等待线程。          

void signalAll() 唤醒所有等待线程。

步骤:

通过Lock接口的实现类获取lock对象,然后调用该接口中的方法:Lock lock = new ReentrantLock();

通过lock对象中已经定义好的创建Condition对象的方法获取其对象,然后调用它的await,signal等方法。

Condition condition = lock.newCondition();

如何只唤醒对方线程?

Condition condition_pro = lock.newCondition()

Condition condition_con = lock.newCondition()

           

11、停止线程:

stop方法已经过时,如何停止线程?

停止线程的方法只有一种,就是run方法结束。如何让run方法结束呢?

开启多线程运行,运行代码通常是循环体,只要控制住循环,就可以让run方法结束,也就是结束线程。

特殊情况:当线程属于冻结状态,就不会读取循环控制标记,则线程就不会结束。

为解决该特殊情况,可引入Thread类中的Interrupt方法结束线程的冻结状态;

当没有指定的方式让冻结线程恢复到运行状态时,需要对冻结进行清除,强制让线程恢复到运行状态

12、守护线程(后台线程)

setDaemon(boolean on):将该线程标记为守护线程或者用户线程。当主线程结束,守护线程自动结束,比如圣斗士星矢里面的守护雅典娜,在多线程里面主线程就是雅典娜,守护线程就是圣斗士,主线程结束了,守护线程则自动结束。

当正在运行的线程都是守护线程时,java虚拟机jvm退出;所以该方法必须在启动线程前调用;

守护线程的特点:

守护线程开启后和前台线程共同抢夺cpu的执行权,开启、运行两者都没区别,

但结束时有区别,当所有前台线程都结束后,守护线程会自动结束。

13、多线程join方法:

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

void join(long millis)  等待该线程终止的时间最长为 millis 毫秒。

throws InterruptedException         

特点:当A线程执行到B线程的join方法时,A就会等待B线程都执行完,A才会执行

作用: join可以用来临时加入线程执行;

示例: main();

t1.start();

t2.start();

t1.join();//读到该句时,主线程把cpu执行权释放掉(注意不是转给t1线程),并等待t1执行完毕.

t2.start();

然后t2与主线程抢夺cpu的执行权。

又如:

main();

t1.start();

t2.start();

t1.join();此时,主线程释放执行权,等t1执行完毕才可去抢夺cpu的执行权。此时,t1t2在抢夺cpu执行权,而不是只有t1在执行!!

也即:主线程遇到谁的join,就等待谁的线程执行完毕。

14、多线程优先级:yield()方法

yield():暂停当前正在执行的线程对象,并执行其他线程

setPriority(int newPriority):更改线程优先级

int getPriority() 返回线程的优先级。

String toString() 返回该线程的字符串表示形式,包括线程名称、优先级和线程组

           

(1)MAX_PRIORITY:最高优先级(10)

(1)Min_PRIORITY:最低优先级(1)

(1)Morm_PRIORITY:默认优先级(5)

15、在静态方法上使用同步时会发生什么事?

同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,

线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。

它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。

------- android培训java培训、期待与您交流! ----------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值