您的位置:首页 > 职场人生

黑马程序员——多线程

2015-10-03 20:54 465 查看
------- android培训java培训、期待与您交流! ----------

导图



一、概述

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类中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: