黑马程序员-----线程

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

 

学习线程这一章的时候,觉得比前面理解有点吃力。所以视频看了好几遍

 

学习多线程前要先了解两个概念进程和线程:

进程:一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫控制单元。

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

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

         其实更细节说明虚拟机jvm,jvm启动不止一个线程,还有负责垃圾回收机制的线程

 

为什么要使用多线程呢? 多线程的意义是什么呢?

提高了程序的执行效率。

 

线程的创建方式有两种:

创建线程的第一种方法(继承Thread类,重写run()方法)

1,  定义类继承Thread。

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

3,  调用线程的start方法,该方法有两个作用,启动线程,调用run方法

创建线程的第二种方法(声明实现Runnable接口,并重写run()方法)

1,  定义类实现Runnable接口

2,  覆盖Runnable接口中的run方法

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

3,  通过Thread类建立线程对象

4,  通过Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

为什么要将Runnable接口的子类对象作为实际参数船体给Thread类的构造函数?

因为自定义的run方法所属的对象是Runnable接口的子类对象。所以要让线程去执行只定对象的Run方法,就必须明确该run方法所属的原因

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

 

我们可以形象把多线程的运行行为在互相抢夺cpu的执行权

 

 

实现方式和继承方式有什么区别呢?

实现方式:避免了单继承的局限性。在定义线程时,建议使用实现方式。

两种方式的区别:

继承Thread:线程代码存放Thread子类run方法中

实现Runable,线程代码存在接口的子类的run方法中

 

线程的五种状态:

 

 

线程中经常用到的方法:

static Thread currentThread():获取当前线程的对象。

getName():获取线程名称。(Thread-编号,默认从0开始)

setName();设置线程名称

toString() ;获取线程名称、优先级 、线程组

setDaemon(Boolean on);该线程标记为守护线程。当正在运行的都是守护线程时,java虚拟机退出。该方法必须在启动线程前调用

join() 等待该线程终止(会抛出异常InterruptedException)当A线程执行到了B线程的Join方法时,A就会等待,等B线程执行完,A才会执行。Join可以用来临时加入线程执行

setPriority() 更改线程的优先级(1-10)主线程main的优先级是5

(Thread.Max_Priority)10

(Thread.Min_priority)  1

(Thread Norm_priority) 5

 yiled() 暂停当前执行的线程对象,执行其他线程.

 

多线程运行过程中会出现安全问题

出现问题的原因

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

解决办法:

对多条操作共享数据的语句,只能让一个线程都执行玩,在执行过程中,其他线程不可以参与执行。

java对多线程的安全问题提供了专业的解决方式。同步代码块

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

{

 需要被同步的代码

}

使用同步的前提:

1,  必要有有两个或者两个以上的线程。

2,  必须是多个线程使用同一个锁。

同步的优缺点:

好处:解决了多线程的安全问题。

弊端:多个线程需要判断锁,较为消耗资源。

如何找问题?

1,明确哪些代码是多线程运行代码。

2,明确共享数据。

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

同步代码块和同步函数

同步代码块:synchronized(obj){ }

同步函数:如:public synchronized void add();

同步函数用的是哪个锁?

函数需要被对象调用,那么函数都有一个所属对象的引用,就是this。所以同步函数使用的锁就是this

 如果同步函数被静态修饰后,使用的锁是什么呢?

通过验证,发现不再是this。因为静态方法也不可以定义this。静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。

类名.class 该对象的类型是class。静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class

 

线程间的通信 其实就是多个线程在操作同一个资源,但是操作的动作不同。

 等待唤醒机制

 Wait: Notify(); notifyAll();

都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。

 为什么这些操作线程的方法要定义Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识它们锁操作线程只有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一把锁。而锁可以是任意对象,所以可以被任意对象调用的方法定义在object中。

 停止线程

 Stop方法已经过时。那么如何停止线程?

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

 特殊情况:

当线程处于冻结状态。就不会读到标记,线程就不会结束。 当没有指定的方式让冻结的线程恢复到运行状态时,这时就需要对冻结进行清除。

强制让线程恢复到运状态中来,这样就可以操作标记让线程结束。Thread 类提供该方法 interrupt();

 

 

 

-------------------------------------------- android培训java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值