黑马程序员-Java基础-多线程

第一讲  多线程概述

1、 定义

进程:是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。在程序运行时,会被分配一个内存空间,进程就用于标识这个空间,封装单元,线程才是线程中真正执行的哦部分。

线程:就是进程中的一个独立的控制单元,线程在控制着进程的执行。

一个进程中至少有一个线程。

例子:java JVM 启动时会有一个进程java.exe。该进程中至少一个线程负责java程序的执行,而且这个线程运行的代码存在于main方法中,该线程就称为主线程。

说明:jvm启动时不止一个线程,还有一个负责垃圾回收机制的线程。

2、  多线程

多线程可以使得多个代码“同步”执行。在单核的前提下,多个线程都在获取cpu的执行权,cpu执行到谁,谁就运行。需要明确的是,在某一个时刻,只能有一个线程在运行。

第二讲  创建线程-继承Tread类

1、  创建线程第一种方式:继承Tread类

步骤:

1)定义类继承Tread类;

2)复写Tread类中的run方法;

3)调用线程的start()方法,该方法有两个作用:启动线程、调用run方法;

2、  run和start方法特性

Thread类用于描述线程,该类就定义了一个功能,用于存放线程要运行的代码,该存储功能就是run方法。主线程把运行的代码存储在main方法中。

复写run方法的目的:将自定义的代码存储在run方法中,让线程运行。

3、  练习:创建两个线程,和主线程交替运行

l  定义线程类继承Tread类

l  创建两个线程;

l  启动两个线程;

代码实现如下:

4、  线程运行状态

线程在运行过程中有如下5中状态:创建、运行、冻结、临时状态(阻塞)、消亡。

这几种状态之间的关系如下:

5、  线程在虚拟机中的名称

获取线程名称:

获取线程名称格式:线程对象.getName();

线程都有自己默认的名称:Thread-编号,该编号从0开始。

设置线程名称:

setName()或构造函数设置线程名称。

Thread类的构造函数和为线程设置名称,因此,可以在定义线程类时,调用Thread类的构造函数来设置线程的名称。

Thread类中的方法currentThread()可以获取到当前运行的线程对象。

获取和设置线程名称的意义:当线程多的时候,可以对线程进行管理。

第三讲  创建线程-实现Runnable接口

1、  多个窗口同时卖票例子

创建多个线程,同时执行卖票功能。

利用继承Thread类方法创建线程,实现多个窗口同时卖票,但票的数量必须定义为静态的,否则会出现多卖的情况。然后我们在写代码时,较少定义静态变量,因为静态变量生存周期较长浪费资源。

因此,就引入了第二种创建线程的方式:实现Runnable接口

2、  创建线程的第二种方式——实现Runnable接口

步骤:

1)  定义类实现Runnable接口;

2)  覆盖Runnable接口中的run方法;

目的:将线程要运行的代码存放在该run方法中。

3)  通过Thread类建立线程对象;

4)  将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数;

要将Runnable接口的子类对象传递给Thread类的构造函数。

因为:自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去指定指定对象的run方法。即,明确该run方法所属的对象。

5)  调用Thread类的start方法,并开启线程,并调用Runnable接口子类的run方法;

代码实现如下:

实现方式与继承方式的对比的好处

l  实现方式可以避免java单继承的局限性,在定义线程时,建议使用实现方式;

l  资源被独立了出来,解决了多窗口卖票的问题;——这个卖票过程只在内存中创建了一个tick,多个卖票线程只能对这个票资源进行操作。

第四讲  多线程安全问题

1、  多线程安全问题概述

问题出现的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句执行了一部分,还没有执行完,就被另一个线程参与进来执行,导致共享数据的错误。

解决办法:对多条操作共享数据的语句,只能让一个线程执行完了,才能让其他线程参与进来。

Java中的解决办法:同步代码块

Synchronized(对象)

{

需要被同步的代码

}

说明:对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

2、  同步使用

同步使用的前提:必须要有两个或两个以上的线程;必须是多个线程使用同一个锁。

同步的好处:解决了多线程的安全问题;

同步的弊端:多个线程需要判断锁,较为耗费资源;

3、  同步的表现形式

同步代码块

代码示例:

同步函数

4、  同步中的锁

1)         同步代码块的锁可以 是任意的对象;

2)         同步代函数的锁是this(函数所在类的实例对象);

3)         同步静态函数的锁是该类对应的字节码文件对象,类名.class;

第五讲  同步在单例设计模式中的应用

1、  概述

单例设计模式有两种体现方式:饿汉式和懒汉式。

因为懒汉式是函数被调用时才会创建对象,而创建对象的语句不止一条,所以在多线程时容易出现安全隐患。

2、  解决懒汉式安全问题方法

将获取对象的函数定义为同步的,如下:

但每次调用该函数时都需要判断锁,影响运行效率,可以通过双重判断形式来稍微提高运行效率,如下。这样,可以减少锁的次数,但代码增多了。

3、  死锁

同步中嵌套同步,而且同步的锁不一样。而且不同线程都在等待对方的锁。

知识点总结

1、  创建线程有两种方式:继承Thread类;实现Runnable接口

实现Runnable接口可以解决多结成问题,还能将资源独立出来,保证资源的唯一性。

2、  多线程的出现使得很多程序可以“同时”运行,但可能会出现共享数据错误,造成多线程安全问题,此时,可以通过同步机制来进行控制,同步包括:同步代码块、同步函数。

3、  使用同步代码块时,需要明确如下问题:

1)  明确哪些代码是多线程运行代码(run方法中的代码);

2)  明确共享数据;

3)  明确多线程运行代码中哪些是操作共享数据的;

4、  懒汉式同步问题

懒汉式的实例是延迟加载的,而且存在多条操作语句,在多线程情况下可能会出现安全问题。此时可以用同步函数或同步代码块来控制,但每次获取实例时都需要判断锁影响效率,我们可以通过双重判断的方式来减少判断锁的次数,从而稍微的提高了运行效率。但实际应用过程中,建议使用饿汉式。

时间: 2024-11-06 22:53:02

黑马程序员-Java基础-多线程的相关文章

黑马程序员——java基础——多线程

 黑马程序员--java基础--多线程 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 进程:是一个正在执行中的程序.每一个进程执行都有一个执行顺序.该顺序是一个执行路径,或者叫一个控制单元. 线程:就是进程中的一个独立的控制单元.线程在控制着进程的执行.一个进程中至少有一个线程. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序,每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量.

黑马程序员--Java基础--多线程|线程同步

--Java培训.Android培训.iOS培训..Net培训 期待与您共同交流!-- 多线程基础.线程同步 1. 多线程基础 1.1. 进程和线程 1.1.1. 什么是进程 所谓进程(process)就是一块包含了某些资源的内存区域.操作系统利用进程把它的工作划分为一些功能单元.进程中所包含的一个或多个执行单元称为线程(thread).进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问.线程只能归属于一个进程并且它只能访问该进程所拥有的资源.当操作系统创建一个进程后,该进程会自动

黑马程序员-java基础-多线程2

5.多线程的安全问题:多线程同步 当使用多个线程同时访问一个数据时,经常会出现线程安全问题.如下面程序: 1 package Thread; 2 3 /* 4 * 多个线程同时访问一个数据时,出现的安全问题. 5 * 模拟一个卖火车票系统:一共有100张票,多个窗口同时卖票 6 */ 7 class Ticks implements Runnable 8 { 9 private int ticks = 100 ; 10 public void run() 11 { 12 while (ticks

黑马程序员——java基础---多线程

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 学习多线程之前,需对以下几个概念有所认知: 进程:进程是动态的.是一个正在执行中的程序.每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 线程:线程依附于进程,可以理解为进程下的一个子执行路径,但没有进程线程无法单独执行. 两者间的区别:进程是重量级的计算机任务,需要给它分配独立的地址空间和系统资源等.不同进程的内部数据和状态都是完全独立,所以不同进程之间的通信或转换

黑马程序员——java基础---多线程(二)

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! -------  线程间的通信:简单来说,就是多个线程在操作同一资源,但操作的动作不同. 试想一下,对于同一个资源做不同的操作,这势必会在操作的过程中产生矛盾.为了避免这种情况的发生,就需要用的synchronized来保证,每次对共享资源的操作,只能是一条线程在进行.在用到同步的时候,就会因需求问题用到wait().notify().notifyAll()这三个方法. wait()方法:作用是使调用线程自动

黑马程序员-java基础-多线程1

---恢复内容开始--- 单线程的程序只有一个顺序流:而多线程的程序则可以包括多个顺序执行流,并且多个顺序流之间互不干扰.就像单线程程序如同只雇佣了一个服务员的餐厅,他只有做完一件事情后才可以做下面一件事情:而多线程程序则是雇佣了多名服务员的餐厅,他们可以同时进行着多件事情. JAVA多线程编程的相关知识:创建.启动线程.控制线程.以及多线程的同步操作. 1.概述: 进程是指正在运行中的程序.每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或叫一个执行单元. 线程是指进程中能够独立执行的控

黑马程序员——Java基础知识之多线程协同

多线程协同 线程间的通讯:对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤,但是他们共享了一个资源. 怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,用对象把这车装满,现在一车装一个对象. 等待唤醒机制: 用的不是sleep是wait.flag标记,这是两人沟通的方式.其实每个标记就要做一次等待或者notify,判断wait,改值notify.线程池.notify唤醒里面的线程,按顺序唤醒.wait和notify必须用在

黑马程序员——Java基础---IO(下)

黑马程序员——Java基础---IO(下) ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供了File类.properties类.打印流.序列流等和输入输出相关的类,它们能够帮助我们更好的处理信息.下面将对它们进行简单的介绍. 一.正

黑马程序员——Java基础---集合框架工具类

黑马程序员——Java基础<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java为操作Set.List和Map提供了一系列工具类,主要有Collections和Arrays.这两个工具类的特点:类中的方法都是静态的,不需要创建对象,直接使用类名调用即可.Collections:是集合对象