黑马程序员——多线程
2015-10-03 20:54
465 查看
------- android培训、java培训、期待与您交流! ----------
是一个正在执行中的程序。每一个程序执行都有一个执行顺序。该顺序是一个路径,或者叫一个控制单元。
2、线程:就是进程中一个独立的控制单元。线程序控制着进程执行。
一个进程至少有一个线程(多线程)。java启动时会有一个进程java.exe该进程中至少有一个线程负责java程序的执行而且这个线程运行的代码存在于main方法中该线程称之为主线程
扩展:其实更细节说明jvm 启动不止一个线程,还有负责垃圾回收的机制线程。
通过APi的查找,java已经提供了对线程事物的描述,就thread类。创建线程的第一种方法,就是继承Thread类。
步骤:
1.定义继承类Thread
2.复写Thread类中的run方法
3.调用线程的start方法。
该方法两个作用:启动线程调用run方法
进程运行有五种状态:被创建、运行、冻结、阻塞、消亡。它们之间的转化关系如下:
线程都有自己的名称 Thread-编号从0开始。用static Thread.currentThread();可以获取当前对象;用getName();获取线程名称;设置线程名称用etName或者构造函数。
1、 定义类实现Runnable接口;
2、 覆盖Runnable中的run方法,将线程要运行的代码存放在该run方法中;
3、 通过Thread类创建对象;
4、 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。为什么要将Runnable接口的子类对象传给Runnable的构造函数呢?因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确run方法所属对象。
这种现实方式和第一种继承方式有什么区别呢?
避免了单继承的局限性,在定义线程时,建议使用实现方式。
在同步函数被静态和,使用的锁是什么呢?
通过验证,发现不再是this。因为静态方法中不可以定义this。静态进内存时,内存中没有本类对象,但是一定有该类的字节码文件对象(类名.class)。该对象的类型是class。
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另个线程参与进来执行,导致共享数据出错。
2、解决办法
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他程序不可以参与执行。Java对于多线程的安全问题提供了专业的解决方式就是同步代码块,格式如下:
Synchronized(对象)
{
需要同步的代码
}
对象如同锁一样,持有锁的进程可以在同步中执行,没有持有锁的程序即使获取CPU的执行权,也进不去,因为没有获取锁。
那么如何寻找其中的安全问题呢?
首先要明确哪些代码是多进程运行代码;其次,明确共享数据;然后明确多线程运行代码中哪些语句操作共享数据。
进程安全问题当中除了有以上情况之外还有一种情况叫死锁。死锁就是同步中嵌套同步,而所持有的锁不一样的情况。死锁在实际开发中要避免。
为什么这些方法在操作同步线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的线程才可以被同一个锁上的notify唤醒。不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在objec类中
导图
一、概述
1、进程是一个正在执行中的程序。每一个程序执行都有一个执行顺序。该顺序是一个路径,或者叫一个控制单元。
2、线程:就是进程中一个独立的控制单元。线程序控制着进程执行。
一个进程至少有一个线程(多线程)。java启动时会有一个进程java.exe该进程中至少有一个线程负责java程序的执行而且这个线程运行的代码存在于main方法中该线程称之为主线程
扩展:其实更细节说明jvm 启动不止一个线程,还有负责垃圾回收的机制线程。
二、多线程的创建
1.如何在定义的代码中,自定义一个线程呢?通过APi的查找,java已经提供了对线程事物的描述,就thread类。创建线程的第一种方法,就是继承Thread类。
步骤:
1.定义继承类Thread
2.复写Thread类中的run方法
3.调用线程的start方法。
该方法两个作用:启动线程调用run方法
三、运行
发现运行的每一次一结果都不一样因为多个线程执行获取CPU执行权,cpu执行到谁,谁就运行。明确一点,在某一时刻,只有一个程序在运行(多核除外)。CPU在做着快速切换,以达到看法上是在同时运行的效果。我们可以形像看成多线程运行在抢夺CPU执行权。这就是多线程的一个特性:随机性,随抢到随执行,至于执行多长时间,由cpu决定。进程运行有五种状态:被创建、运行、冻结、阻塞、消亡。它们之间的转化关系如下:
线程都有自己的名称 Thread-编号从0开始。用static Thread.currentThread();可以获取当前对象;用getName();获取线程名称;设置线程名称用etName或者构造函数。
四、Runable
创建线程有两种方式,前面已经提到第一种方法继承Thread类形式创建。那么第二种方法就是实现Runnable接口。步骤如下:1、 定义类实现Runnable接口;
2、 覆盖Runnable中的run方法,将线程要运行的代码存放在该run方法中;
3、 通过Thread类创建对象;
4、 将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。为什么要将Runnable接口的子类对象传给Runnable的构造函数呢?因为,自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去指定对象的run方法,就必须明确run方法所属对象。
这种现实方式和第一种继承方式有什么区别呢?
避免了单继承的局限性,在定义线程时,建议使用实现方式。
在同步函数被静态和,使用的锁是什么呢?
通过验证,发现不再是this。因为静态方法中不可以定义this。静态进内存时,内存中没有本类对象,但是一定有该类的字节码文件对象(类名.class)。该对象的类型是class。
五、安全问题
1、出现问题的原因当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另个线程参与进来执行,导致共享数据出错。
2、解决办法
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他程序不可以参与执行。Java对于多线程的安全问题提供了专业的解决方式就是同步代码块,格式如下:
Synchronized(对象)
{
需要同步的代码
}
对象如同锁一样,持有锁的进程可以在同步中执行,没有持有锁的程序即使获取CPU的执行权,也进不去,因为没有获取锁。
那么如何寻找其中的安全问题呢?
首先要明确哪些代码是多进程运行代码;其次,明确共享数据;然后明确多线程运行代码中哪些语句操作共享数据。
进程安全问题当中除了有以上情况之外还有一种情况叫死锁。死锁就是同步中嵌套同步,而所持有的锁不一样的情况。死锁在实际开发中要避免。
六、通信
在线程通信中有wait、notify、notifyAll方法使用在同步中,因为要对持有监视器(锁)的进为什么这些方法在操作同步线程时,都必须要标识它们所操作线程持有的锁,只有同一个锁上的线程才可以被同一个锁上的notify唤醒。不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在objec类中
相关文章推荐
- 黑马程序员——java基础之List集合
- 编程面试题002——splitIp
- 【小米面试题】-给定一个具体时间,计算时针与分针之间的角度
- 轻松搞定面试中的二叉树题目
- 轻松搞定面试中的链表题目
- 编程面试题001——wordcount
- 【笔试】46、两个链表的第一个公共结点
- MBA职场:如何从技术人员变成管理大牛
- J2SE基础常见面试题目
- 30到运维面试题
- 黑马程序员-----Foundation框架学习之NSArray学习
- SSH的一些面试题
- 《程序员面试金典》--求集合栈
- KMP算法
- Manacher算法
- 面试题25:二叉树中和为某一值的路径
- 一个老程序员的5点建议
- 系统程序员成长计划读后感
- 金蝶面试题汇总
- 国外 程序员的十个等级,看看你是那个等级?