黑马程序员----多线程3
来源:互联网 发布:linux 僵尸进程 编辑:程序博客网 时间:2024/05/22 20:21
等待唤醒机制:
涉及的方法:
1,wait();让线程处于冻结状态,被wait的线程会被存到线程池中。(线程池到底又是个什么东西!)
2,notify();唤醒线程池中一个线程(任意)。
3,notifyAll();唤醒线程池中全部线程。
这些方法都必须定义在同步中。(为什么?)
因为这些方法是用于操作线程状态的方法,必须要明确操作的是哪个锁上的线程。
wait();是用来操作线程的,但是居然不在线程类里面。为什么在Object里面?
为什么操作线程的方法wait(),notify(),notifyall定义在了object类里面?
原因是:因为这些是监视器的方法,监视器其实就是锁。而锁呢?可是是任意对象嘛,任意的对象调用的方式一定是定义在Object类中。
所谓的对象监视器-----就是锁
要求理解这个图。
唤醒机制练习:
/*唤醒机制练习:思想:1,建立资源对象,资源对象有资源,就向外提供get 与 set 方法。2,输入、输出资源方法,是对资源同时进行的方法,用到多线程,实现Runnable*///建立资源对象class Resource{private String name; private String sex; private boolean flag = false;//用于线程冻结与唤醒标志位public synchronized void set(String name , String sex)//加锁因在线程里面{if(flag)//真就输入数据try{this.wait();}catch (InterruptedException e){}this.name = name;this.sex = sex;flag = true ;//改标志位,后唤醒this.notify();}public synchronized void out(){if(!flag)try{this.wait();}catch (InterruptedException e){}System.out.println(name+"...+++++...."+sex);flag = false;this.notify();}//建立输入对象class Input implements Runnable{Resource r ;Input(Resource r){this.r = r;}public void run(){int x = 0;//取模判断用于切换模式while(true){if(x == 0){r.set("张山....","男");}else{r.set("媛媛.......","女");}x = x++%2;}}}//描述输出对象class Output implements Runnable{Resource r ;Output(Resource r){this.r = r; }public void run(){r.out();}}}class ResourceDemo {public static void main(String[] args) {//System.out.println("Hello World!");// 创建资源Resource r = new Resource();// 创建任务Input in = new Input(r);Output out = new Output(r);//创建线程Thread t = new Thread(in);Thread t1 = new Thread(out);//开启线程t.start();t1.start();}}
来多生产者,多消费者实例:
线程安全隐患出现,一但出现线程安全隐患,考虑有没有共享数据。
/*生产者,消费者。多生产者,多消费者的问题。if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。while判断标记,解决了线程获取执行权后,是否要运行!notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。notifyAll解决了本方线程一定会唤醒对方线程的问题。*/class Resource{private String name;private int count = 1;private boolean flag = false;public synchronized void set(String name)// {while(flag)//if(flag) //导致线程错过消费的问题点if语句,冻结后继续往下执行,不再判断而导致的问题。//重点了解if和while的区别try{this.wait();}catch(InterruptedException e){}// t1 t0this.name = name + count;//烤鸭1 烤鸭2 烤鸭3count++;//2 3 4System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3flag = true;notifyAll();//为了能唤醒消费的线程。//notify();}public synchronized void out()// t3{while(!flag)//if(!flag)try{this.wait();}catch(InterruptedException e){}//t2 t3System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费烤鸭1flag = false;notifyAll();//notify();}}class Producer implements Runnable{private Resource r;Producer(Resource r){this.r = r;}public void run(){while(true){r.set("烤鸭");}}}class Consumer implements Runnable{private Resource r;Consumer(Resource r){this.r = r;}public void run(){while(true){r.out();}}}class ProducerConsumerDemo{public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);Consumer con = new Consumer(r);Thread t0 = new Thread(pro);Thread t1 = new Thread(pro);Thread t2 = new Thread(con);Thread t3 = new Thread(con);t0.start();t1.start();t2.start();t3.start();}}
多线程(线程间通信-多生产者多消费者问题-JDK1.5新特性-Lock)---------为了解决notifyAll ();
说说把锁封装成对象的原因,以前synchronized是隐式的锁!现在什么时候释放,什么时候锁,都是我们自己说了算!
Condition接口中的方法有自己的实现方法!
以前痛苦的地方就是一个锁上只有一组监视器,这组监视器即监视着生产者又监视着消费者。(其实这里就是解决notifyAll();的方法)
现在考虑:现在可以生产者和消费者都具备一套监视器
问题:以前也可以弄啊?但是是生产者和消费者持有不同的锁才行。
实现方法:
API实例(要求能自己写):
class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0) notEmpty.await(); Object x = items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } finally { lock.unlock(); } } }
要求熟悉的例子:
/*jdk1.5以后将同步和锁封装成了对象。 并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作。Lock接口: 出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作。同时更为灵活。可以一个锁上加上多组监视器。lock():获取锁。unlock():释放锁,通常需要定义finally代码块中。Condition接口:出现替代了Object中的wait notify notifyAll方法。将这些监视器方法单独进行了封装,变成Condition监视器对象。可以任意锁进行组合。await();signal();signalAll();*/import java.util.concurrent.locks.*;class Resource{private String name;private int count = 1;private boolean flag = false;//创建一个锁对象。Lock lock = new ReentrantLock();//通过已有的锁获取该锁上的监视器对象。//Condition con = lock.newCondition();//通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。Condition producer_con = lock.newCondition();Condition consumer_con = lock.newCondition();public void set(String name)// t0 t1{lock.lock();try{while(flag)//try{lock.wait();}catch(InterruptedException e){}// t1 t0try{producer_con.await();}catch(InterruptedException e){}// t1 t0this.name = name + count;//烤鸭1 烤鸭2 烤鸭3count++;//2 3 4System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3flag = true;//notifyAll();//con.signalAll();consumer_con.signal();}finally{lock.unlock();}}public void out()// t2 t3{lock.lock();try{while(!flag)//try{this.wait();}catch(InterruptedException e){}//t2 t3try{cousumer_con.await();}catch(InterruptedException e){}//t2 t3System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);//消费烤鸭1flag = false;//notifyAll();//con.signalAll();producer_con.signal();}finally{lock.unlock();}}}class Producer implements Runnable{private Resource r;Producer(Resource r){this.r = r;}public void run(){while(true){r.set("烤鸭");}}}class Consumer implements Runnable{private Resource r;Consumer(Resource r){this.r = r;}public void run(){while(true){r.out();}}}class ProducerConsumerDemo2{public static void main(String[] args) {Resource r = new Resource();Producer pro = new Producer(r);Consumer con = new Consumer(r);Thread t0 = new Thread(pro);Thread t1 = new Thread(pro);Thread t2 = new Thread(con);Thread t3 = new Thread(con);t0.start();t1.start();t2.start();t3.start();}}
wait(); 和sleep();的区别?
1,wait(); 可以指定时间也可以不指定。(也就是说wait可以是无休止的)
sleep必须指定时间。
2,在同步中时,对cpu的执行权和锁的处理不同。
wait();释放执行权,释放锁
sleep();释放执行权,不释放锁。(这不需要人叫,自己可以醒)
线程什么时候消亡呢?
停止线程方式一:定义标记(有解决不了的问题的时候,是什么呢?)
答案:如果线程处于冻结状态,就不会有机会判断标志位了。那又怎么结束呢?
停止线程:
1,stop方法。
2,run方法结束。
怎么控制线程的任务结束呢?
任务中都会有循环结构,只要控制住循环就可以结束任务。
控制循环通常就用定义标记来完成。(标志位控制)
但是如果线程处于了冻结状态,无法读取标记。如何结束呢?
可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态中来,让线程具备cpu的执行资格。
(恢复到运行状态后再结束线程,就会安全)
当时强制动作会发生了InterruptedException,记得要处理
线程可以调节优先级!
多线程总结:1,进程和线程的概念。|--进程:|--线程:2,jvm中的多线程体现。|--主线程,垃圾回收线程,自定义线程。以及他们运行的代码的位置。3,什么时候使用多线程,多线程的好处是什么?创建线程的目的?|--当需要多部分代码同时执行的时候,可以使用。4,创建线程的两种方式。★★★★★|--继承Thread|--步骤|--实现Runnable|--步骤|--两种方式的区别?5,线程的5种状态。对于执行资格和执行权在状态中的具体特点。|--被创建:|--运行:|--冻结:|--临时阻塞:|--消亡:6,线程的安全问题。★★★★★|--安全问题的原因:|--解决的思想:|--解决的体现:synchronized|--同步的前提:但是加上同步还出现安全问题,就需要用前提来思考。|--同步的两种表现方法和区别:|--同步的好处和弊端:|--单例的懒汉式。|--死锁。7,线程间的通信。等待/唤醒机制。|--概念:多个线程,不同任务,处理同一资源。 |--等待唤醒机制。使用了锁上的 wait notify notifyAll. ★★★★★|--生产者/消费者的问题。并多生产和多消费的问题。 while判断标记。用notifyAll唤醒对方。 ★★★★★|--JDK1.5以后出现了更好的方案,★★★Lock接口替代了synchronized Condition接口替代了Object中的监视方法,并将监视器方法封装成了Condition和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。可以实现一组负责生产者,一组负责消费者。 |--wait和sleep的区别。★★★★★8,停止线程的方式。|--原理:|--表现:--中断。9,线程常见的一些方法。|--setDaemon()|--join();|--优先级|--yield();|--在开发时,可以使用匿名内部类来完成局部的路径开辟。
- 黑马程序员----3多线程
- 黑马程序员----多线程3
- 黑马程序员_day15_多线程3
- 黑马程序员---多线程的学习3
- 黑马程序员_java中的多线程3
- 黑马程序员之java多线程3
- 黑马程序员 多线程
- 黑马程序员:多线程
- 黑马程序员-java多线程
- 黑马程序员--java 多线程
- 黑马程序员_java多线程
- 黑马程序员-java多线程
- 黑马程序员_多线程
- 黑马程序员 多线程
- 黑马程序员_JAVA多线程
- 黑马程序员—多线程
- 黑马程序员- 多线程
- 黑马程序员_多线程
- 关于在做绕开SafeSEH的一个实验时(章节:11.6)一个神奇的事情
- python判断字符串
- Fatal signal 11 (SIGSEGV) at 0x00000048 (code=1)
- proc/sys/net/ipv4/下各项的意义
- 黑马程序员_基础加强_类加载器
- 黑马程序员----多线程3
- mybatis学习 from : http://blog.csdn.net/fairyhawk/article/details/8617549
- poj.2299
- 苹果iOS 8最值得期待的十大特性:支持移动支付
- sql where 1=1和 0=1 的作用
- 解析阿里巴巴为什么选择赴美上市
- java设计模式(行为型)之迭代器模式
- 简要解析JavaBean.
- JavaScript Window- 浏览器对象模型和W3C