黑马程序员--- 学习笔记(第十二天
2014-04-06 12:44
423 查看
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
多线程之间的通信
其实就是多线程在操作同一资源,但是操作的动作不同
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器的线程操作,所以都要使用在
同步中,因为只有同步才具有监视器
为什么这些操作线程方法要定义在Object类中呢?
因为这些方法在操作同步中的线程,都必须要在标识他们的操作线程只有
的锁,只有同一个锁上的被等待线程,可以被同一个锁notify()唤醒,不可以
对不同锁中的线程进行唤醒,也就是说等待和唤醒是同一个锁.
而锁可以使任意对象,所以可以被任意对象调用的方法定义在Object中
一对一生产者,消费者:
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再一次判断标记
为什么定义notifyAll?
因为需要唤醒的对方线程.因为只用notify,容易出现只唤醒本方线程的
情况,导致程序中的所有程序都在等待.
如何只唤醒对方呢?
需要导包:java.util.concurrent.locks;
JDK1.5中提供了多线程升级解决方法.将同步synchronized替换成显示的Lock
操作. 将Object中的wait,notify,notifyAll替换成Condition对象,该对象
可以通过Lock锁进行获取?
Lock lock=new ReentrantLock();
Condition con=lock.newCondition();
在该示例中实现本方只唤醒对方操作?
停止线程
stop方法已经过时?
如何停止线程?只有一种方法就是run方法结束
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以
让run方法结束.也就是线程结束
特殊情况,当线程处于冻结状态,就不会读到标记,那么线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除
,强制性制止过程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供了该方法 interrupt();
守护线程:
setDaemon();
将该线程标志为守护线程,或用户线程就是后台线程
必须在启动线程前调用,主线程运行完毕,守护线程机会结束.jvm虚拟机结束
join();
当A线程执行到了B线程的join方法时,就会等待,等b线程执行完毕.
A才会执行
join可以用来临时加入线程执行
toString();
返回线程名称,线程优先级,线程组
ThreadGroup 线程组几乎用不上,就是谁调用该线程,它就属于哪个组,开发不常见
setPriority();//默认优先级是5
MAX_PRIORITY; //最高优先级10
MIN_PRIORITY; //最低优先级1
NORM_PRIORITY;//默认优先级5
yield(); //暂停当前运行线程
当某些代码需要被同时执行时,就等着成线程对象.
开发通常使用Thread的匿名子类或者Runnable的匿名子类
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
多线程之间的通信
其实就是多线程在操作同一资源,但是操作的动作不同
/* 多线程之间的通信 一个线程负责写,一个线程负责读 */ class Demo { public static void main(String[] args) { Resource r=new Resource(); new Thread(new WriterThread(r)).start(); new Thread(new ReaderThread(r)).start(); } } /*操作共同的资源*/ class Resource { private String name; private String sex; private boolean flag=true; public void setFlag(boolean flag){ this.flag=flag; } public synchronized void setInfo(String name,String sex){ while(flag){ //每次都判断标记 try { wait(); } catch (InterruptedException e) { } } this.name=name; this.sex=sex; flag=true; notifyAll(); } public synchronized void getInfo(){ while(!flag){ try { wait(); } catch (InterruptedException e) { } } System.out.println(name+"-----"+sex); flag=false; notifyAll(); } } /*写入线程*/ class WriterThread implements Runnable { private Resource r; public WriterThread(Resource r){ this.r=r; } public void run(){ int i=0; while(true){ if(i%2==0){ r.setInfo("track","man"); }else{ r.setInfo("赖海娟","女"); } i++; } } } /*读取线程*/ class ReaderThread implements Runnable { private Resource r; public ReaderThread(Resource r){ this.r=r; } public void run(){ while(true){ r.getInfo(); } } }
wait();
notify();
notifyAll();
都使用在同步中,因为要对持有监视器的线程操作,所以都要使用在
同步中,因为只有同步才具有监视器
为什么这些操作线程方法要定义在Object类中呢?
因为这些方法在操作同步中的线程,都必须要在标识他们的操作线程只有
的锁,只有同一个锁上的被等待线程,可以被同一个锁notify()唤醒,不可以
对不同锁中的线程进行唤醒,也就是说等待和唤醒是同一个锁.
而锁可以使任意对象,所以可以被任意对象调用的方法定义在Object中
一对一生产者,消费者:
/* 生产者,消费者 */ class Demo1 { public static void main(String[] args) { Resource r=new Resource(); new Thread(new Producer(r)).start(); new Thread(new Consumer(r)).start(); } } /*共同所操作的资源*/ class Resource { private String ware; private int count=1; private boolean b=false; public String getWare(){ return ware; } public synchronized void proWare(String ware){ while(b) try { wait(); } catch (InterruptedException e) { } this.ware=ware+":::"+count++; b=true; notifyAll(); } public synchronized void conWare(){ while(!b) try { wait(); } catch (InterruptedException e) { } System.out.println("消费--------------"+ware); b=false; notifyAll(); } } /*生产者*/ class Producer implements Runnable { private Resource r; public Producer(Resource r){ this.r=r; } public void run(){ while(true){ r.proWare("商品"); System.out.println("生产-----------"+r.getWare()); } } } /*消费者*/ class Consumer implements Runnable { private Resource r; public Consumer(Resource r){ this.r=r; } public void run(){ while(true) r.conWare(); } }
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再一次判断标记
/* 生产者 消费者 使用JDK1.5提供的解决方案 只唤醒对方的等待线程 */ import java.util.concurrent.locks.*; class Demo2 { public static void main(String[] args) { Resource r=new Resource(); /*两个生产者*/ new Thread(new Producer(r)).start(); new Thread(new Producer(r)).start(); /*两个消费者*/ new Thread(new Consumer(r)).start(); new Thread(new Consumer(r)).start(); } } /*共同所操作的资源*/ class Resource { private String ware; private int count=1; private boolean b=false; private Lock lock=new ReentrantLock(); private Condition con_pro=lock.newCondition(); private Condition con_con=lock.newCondition(); public String getWare(){ return ware; } public void proWare(String ware)throws InterruptedException{ lock.lock(); // 获取锁 while(b) try { con_pro.await(); //等待 } finally { lock.unlock();//释放锁 } this.ware=ware+":::"+count++; b=true; con_con.signalAll();//唤醒对方的等待线程 } public void conWare()throws InterruptedException{ lock.lock(); while(!b) try { con_con.await(); } finally { lock.unlock(); } System.out.println(Thread.currentThread().getName()+"消费--------------"+ware); b=false; con_pro.signalAll(); } } /*生产者*/ class Producer implements Runnable { private Resource r; public Producer(Resource r){ this.r=r; } public void run(){ while(true){ try { r.proWare("商品"); System.out.println(Thread.currentThread().getName()+"生产-----------"+r.getWare()); } catch (InterruptedException e) { e.printStackTrace(); } } } } /*消费者*/ class Consumer implements Runnable { private Resource r; public Consumer(Resource r){ this.r=r; } public void run(){ while(true){ try{ r.conWare(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
为什么定义notifyAll?
因为需要唤醒的对方线程.因为只用notify,容易出现只唤醒本方线程的
情况,导致程序中的所有程序都在等待.
如何只唤醒对方呢?
需要导包:java.util.concurrent.locks;
JDK1.5中提供了多线程升级解决方法.将同步synchronized替换成显示的Lock
操作. 将Object中的wait,notify,notifyAll替换成Condition对象,该对象
可以通过Lock锁进行获取?
Lock lock=new ReentrantLock();
Condition con=lock.newCondition();
在该示例中实现本方只唤醒对方操作?
停止线程
stop方法已经过时?
如何停止线程?只有一种方法就是run方法结束
/* 如何停止线程 清除线程的冻结状态interrupt */ class Demo3 { public static void main(String[] args) { Test t=new Test(); Thread tt=new Thread(t); tt.start(); try { Thread.sleep(5000); tt.interrupt(); //5秒清除线程的冻结状态,重新开始执行 } catch (Exception e) { } } } class Test implements Runnable { public synchronized void run(){ for (int i=0;i<100 ;i++ ) { System.out.println(Thread.currentThread().getName()+"::"+i);
//假如出现wait,则线程冻结 需要清除该状态才可以继续执行 if(i==10) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
开启多线程运行,运行代码通常是循环结构,只要控制住循环,就可以
让run方法结束.也就是线程结束
特殊情况,当线程处于冻结状态,就不会读到标记,那么线程就不会结束
当没有指定的方式让冻结的线程恢复到运行状态,这时需要对冻结进行清除
,强制性制止过程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类提供了该方法 interrupt();
守护线程:
setDaemon();
将该线程标志为守护线程,或用户线程就是后台线程
必须在启动线程前调用,主线程运行完毕,守护线程机会结束.jvm虚拟机结束
join();
当A线程执行到了B线程的join方法时,就会等待,等b线程执行完毕.
A才会执行
join可以用来临时加入线程执行
toString();
返回线程名称,线程优先级,线程组
ThreadGroup 线程组几乎用不上,就是谁调用该线程,它就属于哪个组,开发不常见
setPriority();//默认优先级是5
MAX_PRIORITY; //最高优先级10
MIN_PRIORITY; //最低优先级1
NORM_PRIORITY;//默认优先级5
yield(); //暂停当前运行线程
当某些代码需要被同时执行时,就等着成线程对象.
开发通常使用Thread的匿名子类或者Runnable的匿名子类
/* setDaemon守护线程 join临时加入线程 toString//返回线程名称,优先级,线程组 setPriority//设置优先级 yield//暂停线程运行 */ class Demo4 { public static void main(String[] args) { Thread t1=new Thread(){ public void run(){ for (int i=1;i<=20 ;i++ ) { System.out.println(Thread.currentThread().toString()+":::"+i); /* //当设置为守护线程时,即使wait 主线程运行完 主线程就会结束 if(i==10){ try { wait(); } catch (InterruptedException e) { } } */ } } }; Runnable r=new Runnable(){ public void run(){ for (int i=1;i<=20 ;i++ ) { System.out.println(Thread.currentThread().toString()+":::"+i); /* //当设置为守护线程时,即使wait 主线程运行完 主线程就会结束 if(i==10){ try { wait(); } catch (InterruptedException e) { } } */ } } }; Thread t2=new Thread(r); //t1.setPriority(Thread.MAX_PRIORITY);//设置t1的优先级为10 最大 //t1.setDaemon(true); //设置为守护线程 //t2.setDaemon(true); t1.start(); t2.start(); t1.yield(); //暂停对当前运行线程 本人经测试 看不出啥 是不是单核电脑的忧桑? //主线程 for (int i=1;i<=50 ;i++ ) { System.out.println(Thread.currentThread().toString()+":::"+i); } /* //join();//用来临时加入线程 try { t1.join();// 本人经测试 看不出啥 是不是单核电脑的忧桑? } catch (Exception e) { } */ } }
—————————— ASP.Net+Android+IOS开发、.Net培训、期待与您交流!——————————
相关文章推荐
- 黑马程序员——java基础学习笔记——第十二天
- 黑马程序员 C#学习笔记⑧ StreamReader和StreamWriter
- 黑马程序员_学习笔记13_asp.net之Session原理解析
- 黑马程序员---java学习笔记之负数的二进制、负数的模
- 【黑马程序员】交通灯管理系统_学习笔记
- 【黑马程序员】银行业务调度系统_学习笔记
- 黑马程序员 JAVA学习笔记——java基础 单例设计模式
- 黑马程序员之WinForm编程基础学习笔记:输入宽和高,输出面积。
- 黑马程序员 java学习笔记(day03)
- 黑马程序员_JAVA 学习笔记21 WEB篇8
- 黑马程序员_JAVA 学习笔记28 WEB篇15
- 【黑马程序员】C语言学习笔记之clang指令(二)
- 黑马程序员_毕向东_Java基础视频教程学习笔记(十二)
- 黑马程序员_学习笔记:1) 学习方法与Java概述
- 黑马程序员------学习笔记(1)数组实现班内学生的增删改查操作
- 黑马程序员_学习笔记:8) 常见API:String、StringBuffer、StringBuiler、Integer
- 黑马程序员------学习笔记(5)IO流中字节流操作
- 黑马程序员_学习笔记:15) 网络编程:Socket(udp、tcp)
- 黑马程序员_学习笔记第3天——for、while、函数
- 黑马程序员_ArrayList集合学习笔记