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

黑马程序员——多线程

2013-12-22 18:45 197 查看
 -------
android培训、java培训、期待与您交流! ----------
线程的定义
进程:当前正在执行的程序,代表一个应用程序在内存中的执行区域。

线程:是进程中的一个执行控制单元,执行路径。

一个进程中如果只有一个执行路径,这个程序称为单线程。

一个进程中有多个执行路径时,这个程序成为多线程。

多线程的好处:它的出现可以同时执行多条路径,让多部分代码同时执行,提高了效率

jvm启动不止一个线程,除了主线程,还有负责垃圾回收机制打的线程

创建线程

1,继承Thread

定义类继承Thread

重写run方法(Thread类中的run方法用于存储线程要运行的代码)

把新线程要做的事写在run方法中

创建线程对象

开启新线程,调用start()方法,程序内部会自动执行run方法

Thread类常用方法

1,设置名字

通过构造函数可以传入String类型的名字super(String);

通过setName(String)方法可以设置线程对象的名字

2,获取名字

通过getName()方法获取线程对象的名字

3,获取当前线程对象

Thread.currentThread(),主线程也可以获取

4,休眠

Thread.sleep(毫秒), 控制当前线程休眠若干毫秒1秒= 1000毫秒

5,守护

setDaemon(),该方法在启动前调用。设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程都执行结束后,自动退出

6,加入

join(), 主线程暂停, 等待使用join方法的线程执行结束后,主线程再继续

join(int), 可以等待指定的毫秒之后继续

7,yield停止当前线程,运行其他线程

2,实现Runnable

定义类实现Runnable接口

创建run方法

把新线程要运行的代码存放在run方法中

创建自定义的Runnable对象

创建Thread对象,传入Runnable接口的子类对象

调用start()开启新线程, 内部会自动调用Runnable的run()方法

两种方式的区别

区别一:

由于子类重写了Thread类的run(), 当调用start()时, 直接找子类的run()方法

构造函数中传入了Runnable的引用, 成员变量记住了它, start()调用run()方法时内部判断成员变量Runnable是否为空, 不为空则执行Runnable的run()

区别二:

继承Thread只能是单继承,如果自己定义的线程类已经有了父类,就不能再继承了

实现Runnable接口可以多实现,即使自己定义线程类已经有父类可以实现Runnable接口

继承Thread的好处是:可以直接使用Thread类中的方法,代码简单

弊端是:如果已经有了父类,就不能用这种方法

实现Runnable接口的好处是:即使自己定义的线程类有了父类也没关系,因为有了父类也可以实现接口。而且接口是可以多实现的

弊端是:不能直接使用Thread中的方法。需要先获取到线程对象后,才能得到Thread的方法,代码复杂

wait()和sleep()有什么区别?

对时间的指定。

1,sleep方法必须指定时间。

2,wait方法有重载形式,可以指定时间,也可以不指定时间。

对于执行权和锁的操作.

1,sleep():释放执行权,不释放锁,因为肯定能醒,肯定可以恢复到临时阻塞状态。

2,wait():释放执行权,释放锁。

线程之间的同步

当多线程并发,有多段代码同时执行时, 我们希望某一段代码执行的过程中CPU不要切换到其他线程工作,这时就需要同步

如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束之前,不会执行另外一段代码。

同步代码块

格式:

synchronized(对象)

{//该对象可以是任意对象

需要同步的代码;

}

同步中执行同步可以解决安全问题的根本原因就在那个对象上,对象如同锁的功能,持有锁的线程可以执行(例子:火车卫生间)

同步的特点:

同步的前提:

同步需要两个或者两个以上的线程。

多个线程使用的是同一个锁。

未满足这两个条件,不能称其为同步。

同步的好处:

同步的出现解决了多线程的安全问题。

同步的弊端:

当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率

同步函数

使用synchronized关键字修饰一个方法。该函数中所有的代码都是同步的

非静态同步方法默认使用当前对象this作为锁对象

静态同步函数的锁

静态函数使用的锁肯定不是this,因为静态函数中不可以定义this

静态随着类的加载而加载,这时有可能内容还没有该类的对象,但是一个类加载进内存,会先将这个类对应的字节码文件封装成对象,该对象的表示方式:类名.class

线程之间的通信

如果希望线程等待,就调用wait()

如果希望唤醒等待的线程,就调用notify();

这两个方法必须在同步代码中执行, 并且使用同步锁对象来调用

多个线程通信的问题

notify()方法是随机唤醒一个线程(优先唤醒先等待的线程)

notifyAll()方法是唤醒所有线程

JDK1.5之前无法唤醒指定的一个线程

如果多个线程之间通信, 需要使用notifyAll()通知所有线程, 用while来反复判断条件

1.5中提供了多线程升级解决方案:

将同步Synchronized替换成现实Lock操作,

将object中wait,notify,notifyAll替换成了Condition对象

该对象可以通过Lock锁进行获取 lock.newCondition()

停止线程:

run方法结束,只有控制循环,就可以让run方法结束。

特殊情况:

当线程处于冻结状态,就不会读取到标记,线程不会结束。

当没有指定的方发让冻结的线程恢复到运行状态时,这时需要对冻结进行清除

强制让线程恢复到运行状态中,这样就可以操作标记让线程结束

Thread类提供该方法 interrupt()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: