黑马程序员------毕老师视频笔记第十二天------多线程(3)
2014-05-28 19:02
615 查看
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
(回顾)
多线程导致安全问题的原因:
l 多个线程访问出现延迟
l 线程随机性
ps:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的
解决多线程安全问题的方法------同步synchronized
格式
synchronized(对象){需要同步的代码;}
同步可以解决安全问题的根本原因就在那个对象上,该对象如同锁的功能
同步的前提:
l 同步需要两个或两个以上的线程
l 多个线程使用同一把锁
为满足这两个条件,不能称其为同步
同步的弊端:
当线程相当多时,每个线程都会去判断同步上的锁,这是很耗资源的,无形中会降低程序的运行效率
同步函数:
格式:在函数上加上synchronized 修饰符即可
一般函数用的锁是this
静态同步函数用的锁是所在类的Class对象,即字节码文件对象
线程状态:
New新建状态
Runnable可运行(就绪)状态
Running运行(正在运行)状态
Block阻塞(挂起)状态
Dead死亡状态
七.线程间通信
多个线程在操作同一个资源,但是操作的动作不同。
线程间通信---等待唤醒机制
public final void wait()throwsInterruptedException
public final void notify()
public final void notifyAll()
这三个函数都是用在同步中,因为要持有监视器(锁)的线程操作
思考:wait(),notify(),notifyAll()用来操作线程的方法为什么定义在了Object类中?
因为这些方法在操作同步中,线程同步都需要标识他们所操作线程持有的锁,只有同一个锁上被等待的线程,可以被同一个锁的notify唤醒,不可以对不同所中的线程进行等待唤醒。也就是说,等待和唤醒必须是同一个锁,所以要使用在同步中,因为只有同步才具有锁。
一言以蔽之,调用这些函数的对象是锁,锁可以使任意对象,所以这些方法一定要定义在Object类中。
wait和sleep的区别:
1.wait定义在Object类中,被锁调用,sleep定义在Thread类中,被线程调用
2.wait之后持锁线程进入Block状态,放锁,sleep之后线程进入Block状态,不放锁
3.wait之后需要notify或notifyAll唤醒,sleep之后时间到了会自动醒来进入Runnable状态
wait和sleep都声明抛出了中断异常
jdk1.5版本是Java一个里程碑式的改革,对于线程通信来说,将隐式的锁机制改成了显示的锁机制。
解决线程安全问题使用的同步形式,实际上就是锁机制。
而线程同步过程中,获取锁或者是释放锁,只有锁是最清楚的,所以将锁封装成了一个对象,就是Lock对象。
在jdk1.5以后的版本中,将Lock定义成一个接口,位于java.util.concurrent.locks包中。
public interfaceLock
而且,又定义了一些类直接实现这个接口
public classReetrantLock extends Object implements Lock,Serializable
public staticclass ReentrantReadWriteLock.ReadLock extends Object implementsLock,Serializable
public staticclass ReentrantReadWriteLock.WriteLock extends Object implementsLock,Serializable
这三个类实现了Lock接口
Lock接口中用void lock()获取锁,用void unlock()释放锁
在线程通信的等待唤醒机制中,原来用来等待和唤醒的功能wait、notify、notifyAll方法位于Object类中,现在变成await()、signal、signalAll封装在Condition对象中。
Condition也是一个接口,要创建某个锁对应的condition对象,应该这么定义
Lock lock = newRerntrantLock();
Condition c =lock.newCondition();
c.await();
c.signal();
八.多线程常用API
Thread中常用的API有
static Thread currentThread();返回当前正在运行的线程
String getName() 返回该线程的名称
boolean isDaemon() 测试该线程是否为守护线程
void setDaemon() 将该线程设置为守护线程,需在启动线程前调用
void join() 在当前运行的线程中临时加入一个线程
void setPriority() 设置当前线程的优先级
int getPriority() 获得线程的优先级
static void sleep(long millis) 使该线程放弃执行权,进入休眠,时间到自动转醒
void interrupt() 中断线程
示例:
![](http://img.blog.csdn.net/20140528190105265?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd293b2ppYWppYXdvd29qaWFqaWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
用Lock修改示例如下:
![](http://img.blog.csdn.net/20140528190159828?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd293b2ppYWppYXdvd29qaWFqaWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
(回顾)
多线程导致安全问题的原因:
l 多个线程访问出现延迟
l 线程随机性
ps:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的
解决多线程安全问题的方法------同步synchronized
格式
synchronized(对象){需要同步的代码;}
同步可以解决安全问题的根本原因就在那个对象上,该对象如同锁的功能
同步的前提:
l 同步需要两个或两个以上的线程
l 多个线程使用同一把锁
为满足这两个条件,不能称其为同步
同步的弊端:
当线程相当多时,每个线程都会去判断同步上的锁,这是很耗资源的,无形中会降低程序的运行效率
同步函数:
格式:在函数上加上synchronized 修饰符即可
一般函数用的锁是this
静态同步函数用的锁是所在类的Class对象,即字节码文件对象
线程状态:
New新建状态
Runnable可运行(就绪)状态
Running运行(正在运行)状态
Block阻塞(挂起)状态
Dead死亡状态
七.线程间通信
多个线程在操作同一个资源,但是操作的动作不同。
线程间通信---等待唤醒机制
public final void wait()throwsInterruptedException
public final void notify()
public final void notifyAll()
这三个函数都是用在同步中,因为要持有监视器(锁)的线程操作
思考:wait(),notify(),notifyAll()用来操作线程的方法为什么定义在了Object类中?
因为这些方法在操作同步中,线程同步都需要标识他们所操作线程持有的锁,只有同一个锁上被等待的线程,可以被同一个锁的notify唤醒,不可以对不同所中的线程进行等待唤醒。也就是说,等待和唤醒必须是同一个锁,所以要使用在同步中,因为只有同步才具有锁。
一言以蔽之,调用这些函数的对象是锁,锁可以使任意对象,所以这些方法一定要定义在Object类中。
wait和sleep的区别:
1.wait定义在Object类中,被锁调用,sleep定义在Thread类中,被线程调用
2.wait之后持锁线程进入Block状态,放锁,sleep之后线程进入Block状态,不放锁
3.wait之后需要notify或notifyAll唤醒,sleep之后时间到了会自动醒来进入Runnable状态
wait和sleep都声明抛出了中断异常
jdk1.5版本是Java一个里程碑式的改革,对于线程通信来说,将隐式的锁机制改成了显示的锁机制。
解决线程安全问题使用的同步形式,实际上就是锁机制。
而线程同步过程中,获取锁或者是释放锁,只有锁是最清楚的,所以将锁封装成了一个对象,就是Lock对象。
在jdk1.5以后的版本中,将Lock定义成一个接口,位于java.util.concurrent.locks包中。
public interfaceLock
而且,又定义了一些类直接实现这个接口
public classReetrantLock extends Object implements Lock,Serializable
public staticclass ReentrantReadWriteLock.ReadLock extends Object implementsLock,Serializable
public staticclass ReentrantReadWriteLock.WriteLock extends Object implementsLock,Serializable
这三个类实现了Lock接口
Lock接口中用void lock()获取锁,用void unlock()释放锁
在线程通信的等待唤醒机制中,原来用来等待和唤醒的功能wait、notify、notifyAll方法位于Object类中,现在变成await()、signal、signalAll封装在Condition对象中。
Condition也是一个接口,要创建某个锁对应的condition对象,应该这么定义
Lock lock = newRerntrantLock();
Condition c =lock.newCondition();
c.await();
c.signal();
八.多线程常用API
Thread中常用的API有
static Thread currentThread();返回当前正在运行的线程
String getName() 返回该线程的名称
boolean isDaemon() 测试该线程是否为守护线程
void setDaemon() 将该线程设置为守护线程,需在启动线程前调用
void join() 在当前运行的线程中临时加入一个线程
void setPriority() 设置当前线程的优先级
int getPriority() 获得线程的优先级
static void sleep(long millis) 使该线程放弃执行权,进入休眠,时间到自动转醒
void interrupt() 中断线程
示例:
//主线程 class ThreadDemo { public static void main(String[] args) { //定义临界资源 Resource res = new Resource(); //定义两个线程负责存入和取出,并启动 /* Deposit d = new Deposit(res); Remove r = new Remove(res); Thread deposit = new Thread(d); Thread remove = new Thread(r); deposit.start(); remove.start(); */ new Thread(new Deposit(res)).start(); new Thread(new Remove(res)).start(); System.out.println("main over"); } } //定义临界资源 class Resource { int goodsItem = 0; boolean isEmpty = true; public void deposit() { while(goodsItem<100) { synchronized(this) { while (!isEmpty) try{wait();}catch (InterruptedException e){} System.out.print("in:"+goodsItem+" "); goodsItem++; isEmpty = false; notify(); } } } public void remove() { while(goodsItem<100) { synchronized(this) { while (isEmpty) try{wait();}catch (InterruptedException e){} System.out.println("out:..........."+goodsItem); isEmpty = true; notify(); } } } } //定义存入线程运行代码 class Deposit implements Runnable { private Resource res = null; Deposit(Resource res) { this.res = res; } public void run() { res.deposit(); } } //定义取出线程运行代码 class Remove implements Runnable { private Resource res = null; Remove(Resource res) { this.res = res; } public void run() { res.remove(); } }
用Lock修改示例如下:
import java.util.concurrent.locks.*; //主线程 class ThreadDemo { public static void main(String[] args) { //定义临界资源 Resource res = new Resource(); //定义两个线程负责存入和取出,并启动 /* Deposit d = new Deposit(res); Remove r = new Remove(res); Thread deposit = new Thread(d); Thread remove = new Thread(r); deposit.start(); remove.start(); */ new Thread(new Deposit(res)).start(); new Thread(new Remove(res)).start(); System.out.println("main over"); } } //定义临界资源 class Resource { int goodsItem = 0; boolean isEmpty = true; Lock lock = new ReentrantLock(); Condition con = lock.newCondition(); public void deposit() { while(goodsItem<100) { lock.lock(); try { while (!isEmpty) con.await(); System.out.print("in:"+goodsItem+" "); goodsItem++; isEmpty = false; con.signal(); }catch(Exception e){} finally {lock.unlock();} } } public void remove() { while(goodsItem<100) { lock.lock(); try{ while (isEmpty) con.await(); System.out.println("out:..........."+goodsItem); isEmpty = true; con.signal(); }catch(Exception e){} finally {lock.unlock();} } } } //定义存入线程运行代码 class Deposit implements Runnable { private Resource res = null; Deposit(Resource res) { this.res = res; } public void run() { res.deposit(); } } //定义取出线程运行代码 class Remove implements Runnable { private Resource res = null; Remove(Resource res) { this.res = res; } public void run() { res.remove(); } }
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员------毕老师视频笔记第十一天------多线程(1)
- 黑马程序员------毕老师视频笔记第十一天------多线程(2)
- 黑马程序员------毕老师视频笔记第六天------面向对象(static关键字)
- 黑马程序员------毕老师视频笔记第七天------面向对象(继承)
- 黑马程序员------毕老师视频笔记第十天------面向对象(包)
- 黑马程序员------毕老师视频笔记第13-17天------泛型
- 黑马程序员------毕老师视频笔记第13-17天------集合Collection-List-(ArrayList、LinkedList)
- 黑马程序员------毕老师视频笔记第六天------面向对象(main函数)
- 黑马程序员------毕老师视频笔记第九天------面向对象(内部类)
- 黑马程序员------毕老师视频笔记第十天------面向对象(异常下)
- 黑马程序员------毕老师视频笔记第13-17天------集合框架(Collection)
- 黑马程序员------毕老师视频笔记第六天------面向对象(对象初始化过程)
- 黑马程序员------毕老师视频笔记第八天------面向对象(接口多态的应用示例)
- 黑马程序员------毕老师视频笔记第七天------面向对象(抽象类)
- 黑马程序员------毕老师视频笔记第五天------面向对象(构造函数)
- 黑马程序员------毕老师视频笔记第六天------面向对象(单例设计模式)
- 黑马程序员------毕老师视频笔记第七天------面向对象(接口)
- 黑马程序员------毕老师视频笔记第八天------面向对象(多态)
- 黑马程序员------毕老师视频笔记第13-17天------JavaAPI(基本数据类型包装类)
- 黑马程序员------毕老师视频笔记第13-17天------JavaAPI(String类、StringBuffer类)(1)