黑马程序员_多线程


------- 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培训、期待与您交流! ----------
标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值