黑马程序员 java 基础 毕向东 面向对象 多线程 通信 优化 jdk 1.5 之后新特性Lock

来源:互联网 发布:mac bootcamp win7 编辑:程序博客网 时间:2024/05/21 10:47

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

黑马程序员 java 基础 毕向东 面向对象 多线程 通信 优化 jdk 1.5 之后新特性Lock

1 线程通信:synchronized 实现 、Object o 作为锁  wait notify notifyAll 应用场景

package day12Thread;/* * 线程间通信 * 其实是多个线程在操作同一个资源 * 但是操作的动作不同 *  * 等待 唤醒机制  *  * wait() * nitify() * notifyAll()  * 都使用在同步中。 * 因为要对持有监视器(锁)的线程操作 * 所以要使用在同步中,只有同步才具有锁 * 为什么这些操作要定义在Object类中 * 因为这些方法在操作同步线程中,都必须 * 标示他们所操作线程中的锁 * 只有同一个锁上的被等待线程, * 可以被同一个锁上的notify 唤醒 * 不可以对不同锁上的线程进行唤醒 *  * 也就是说,等待唤醒的线程必须是同一个锁上 * 而锁可以是任意对象,所以可以被任意对象调用的方法定义在 * Object类 *  * */class Res{String name;String sex;boolean rw=false;}class Input implements Runnable{Res res;public Input(Res res) {this.res=res;}public void run() {boolean flag=true;while (true) {synchronized (res) {if(res.rw)try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}if (flag) {res.name="mike";res.sex="man";}else {res.name="丽丽";res.sex="女";}flag=flag==true?false:true;res.rw=true;res.notify();}}}}class Output implements Runnable{Res res;public Output(Res res) {this.res=res;}public void run() {while (true) {synchronized (res) {if(!res.rw)try {res.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(res.name+"-"+res.sex);res.rw=false;res.notify();}}}}public class InputOutputDemo {public static void main(String[] args) {Res res=new Res();Input input=new  Input(res);Output output=new Output(res);Thread threadIn=new Thread(input);Thread threadOut=new Thread(output);threadIn.start();threadOut.start();}}

2 在上面例子上的优化  


package day12Thread;/* * 线程间通信 * 其实是多个线程在操作同一个资源 * 但是操作的动作不同 *  * 等待 唤醒机制  *  * wait() * nitify() * notifyAll()  * 都使用在同步中。 * 因为要对持有监视器(锁)的线程操作 * 所以要使用在同步中,只有同步才具有锁 * 为什么这些操作要定义在Object类中 * 因为这些方法在操作同步线程中,都必须 * 标示他们所操作线程中的锁 * 只有同一个锁上的被等待线程, * 可以被同一个锁上的notify 唤醒 * 不可以对不同锁上的线程进行唤醒 *  * 也就是说,等待唤醒的线程必须是同一个锁上 * 而锁可以是任意对象,所以可以被任意对象调用的方法定义在 * Object类中 *  * ------------------------------代码优化----------------------------------- * */class Res2{private String name;private String sex;private boolean rw=false;public synchronized void setNameSex(String name,String sex) {if (rw) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}this.name = name;this.sex = sex;rw=true;this.notify();}public synchronized void getSexName() {if (!rw) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(name+"---"+sex);rw=false;this.notify();}}class Input2 implements Runnable{Res2 res;public Input2(Res2 res) {this.res=res;}public void run() {boolean flag=true;while (true) {if (flag) {res.setNameSex("mike","man");}else {res.setNameSex("丽丽","女");}flag=flag==true?false:true;}}}class Output2 implements Runnable{Res2 res;public Output2(Res2 res) {this.res=res;}public void run() {while (true) {res.getSexName();}}}public class InputOutputDemo2 {public static void main(String[] args) {Res2 res=new Res2();//Input2 input=new  Input2(res);//Output2 output=new Output2(res);//Thread threadIn=new Thread(input);//Thread threadOut=new Thread(output);//threadIn.start();//threadOut.start();new Thread(new  Input2(res)).start();new Thread(new Output2(res)).start();}}

3 多个生成者线程 和 多个消费者线程  、notify  和 notifyAll 的区别


package day12Thread;/*对于多个生产者和消费者 * 为什么要定义while 判断标记 * 原因:为了让被唤醒的线程再一次判断标记 *  * 为什么定义notifyAll() * 因为需要唤醒对方线程 * 因为只用notify ,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待 * */public class ProduceConsumeDemo {public static void main(String[] args) {Resource resource=new Resource();Produce produce=new Produce(resource);Consume consume=new Consume(resource);Thread threadPro1=new Thread(produce);Thread threadPro2=new Thread(produce);Thread threadConsumee1=new Thread(consume);Thread threadConsumee2=new Thread(consume);threadPro1.start();threadPro2.start();threadConsumee1.start();threadConsumee2.start();}}class Produce implements Runnable{private Resource resource;public Produce(Resource resource) {this.resource=resource;}public synchronized void run() {while (true) {resource.set("+商品+");}}}class Consume implements Runnable{private Resource resource;public Consume(Resource resource) {this.resource=resource;}public synchronized void run() {while (true) {resource.out();}}}class Resource{private String name;private int count =1;private boolean flag=false;public synchronized void set (String name){//if(flag){   因为多个生成多个消费 线程 唤醒后没有重新判断,所以会出现线程全部等待while(flag){ try {wait();} catch (InterruptedException e) {e.printStackTrace();}}this.name=name+"--"+count++;System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);flag=true;//this.notify();//会唤醒线程池中最早等待的线程this.notifyAll();//唤醒线程池中所有等待的线程。唤醒对方线程}public synchronized void out() {while(!flag){try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName()+"----消费者----"+this.name);flag=false;this.notifyAll();}}

4使用java 新特性 Lock 代替synchronized 实现同步和线程通信。
将 Object 中的 wait notify notifyAll 替换了Condition 对象,实现了本方只唤醒对方线程操作



package day12Thread;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/*对于多个生产者和消费者 * 为什么要定义while 判断标记 * 原因:为了让被唤醒的线程再一次判断标记 *  * 为什么定义notifyAll() * 因为需要唤醒对方线程 * 因为只用notify ,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待 *  *  * jdk 1.5 中国提供了多线程升级解决方案 * 将同步 的synchronized替换成Lock操作 * 将 Object 中的 wait  notify   notifyAll 替换了Condition  对象 * 该对象可以Lock锁进行获取 * 在该例子中,实现了本方只唤醒对方线程操作 * */public class ProduceConsumeLockDemo {public static void main(String[] args) {Resource2 resource=new Resource2();Produce2 produce=new Produce2(resource);Consume2 consume=new Consume2(resource);Thread threadPro1=new Thread(produce);Thread threadPro2=new Thread(produce);Thread threadConsume2e1=new Thread(consume);Thread threadConsume2e2=new Thread(consume);threadPro1.start();threadPro2.start();threadConsume2e1.start();threadConsume2e2.start();}}class Produce2 implements Runnable{private Resource2 resource;public Produce2(Resource2 resource) {this.resource=resource;}public  void run() {while (true) {try {resource.set("+商品+");} catch (InterruptedException e) {e.printStackTrace();}}}}class Consume2 implements Runnable{private Resource2 resource;public Consume2(Resource2 resource) {this.resource=resource;}public  void run() {while (true) {try {resource.out();} catch (InterruptedException e) {e.printStackTrace();}}}}class Resource2{private String name;private int count =1;private boolean flag=false;//---------------------------------------------------------private Lock lock =new ReentrantLock();private Condition con_Produce=lock.newCondition();private Condition con_Consume=lock.newCondition();//---------------------------------------------------------public  void set (String name)throws InterruptedException {lock.lock();//----------------------- try {while(flag){ //con.await();con_Produce.await();}this.name=name+"--"+count++;System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);flag=true;//con.signal();//con.signalAll();//还是唤醒了所有线程con_Consume.signal();}finally{lock.unlock();//--------------//释放锁的动作一定要执行}}public  void out() throws InterruptedException{lock.lock();//进来,先拿到锁try {while(!flag){con_Consume.await();}System.out.println(Thread.currentThread().getName()+"----消费者----"+this.name);flag=false;//con.signal();con_Produce.signal();}finally{lock.unlock();}}}


5 Thread 的stop()  interrup ()方法  已经 守护线程/用户线程  简介

package day12Thread;/* * stop 方法以及过时 * 如何停止线程 * 只有一种方法 run 方法 运行结束 *  * 开启多线程运行,运行代码通常是循环结构 * 只要控制住循环,就可以让run方法结束,也就是线程结束 *  * 特殊情况 * 当线程处于冻结状态,就不会读到标记 * 那么线程就不会结束 *  * interrupt 强制将冻结状态的线程 运行起来   * 当没有指定的方式让冻结的线程回复都爱运行状态时 *  * 这时需要对冻结状态进行清除 * 强制让线程恢复到运行状态中来,就可以操作标记你,让线程结束 * Thread类 interrupt 提供了该功能 *  * 守护线程 或者 用户线程 *  * 标记为后台线程  : * 处理结束和普通线程有区别外,其他都一样 * 当所有前台线程都结束后,后台线程自动结束(有依赖的意思) * 主线程是前台线程。 * 当正在运行的线程都是守护线程是。jvm自动停止 * */public class StopThreadDemo {public static void main(String[] args) {StopThread st=new StopThread();Thread t1=new Thread(st);Thread t2=new Thread(st);t1.setDaemon(true);t2.setDaemon(true);t1.start();t2.start();int num=0;while (true) {if (num++==60) {//st.changFlag();//t1.interrupt();//t2.interrupt();break;}System.out.println(Thread.currentThread().getName()+"main -"+num);}System.out.println("over");}}class StopThread implements Runnable{private boolean flag=true;public synchronized void run() {while(flag){try {wait();} catch (InterruptedException e) {//e.printStackTrace();System.out.println(Thread.currentThread().getName()+"----InterruptedException");flag=false;}System.out.println(Thread.currentThread().getName()+"----run");}}public void changFlag(){flag=false;}}

6  Thread  的join ()方法简介

package day12Thread;/* * 当 A线程执行到了 B线程的Join方法时 * A线程就会等待B线程终止,A才会 执行 * join可以用来临时加入线程执行 *  * Thread[Thread-0,5,main]--- run29Thread[Thread-1,5,main]--- run32Thread[Thread-0,5,main]--- run30Thread【线程名,优先级,线程组】 一般谁开启了线程,线程属于哪个组优先级 代表 使用cpu 的使用频率默认优先级是  5优先级 分 1 ----10 级static int MAX_PRIORITY     10          线程可以具有的最高优先级。 static int MIN_PRIORITY     1          线程可以具有的最低优先级。 static int NORM_PRIORITY    5          分配给线程的默认优先级。  * */public class ClassJoinDemo  {public static void main(String[] args) throws Exception {JoinDmeo joinDmeo=new JoinDmeo();Thread thread1=new Thread(joinDmeo);Thread thread2=new Thread(joinDmeo);thread1.start();//thread1.setPriority(Thread.MAX_PRIORITY);//thread1.join();/*thread1.join(); * thread1 请求执行权 * 主线程处于冻结状态 * thread1 结束后 主线程才恢复到运行状态 * 等待这个线程 终止 * 当进行多线程运行时, * 临时加入一个线程,让这个线程运算完, * */thread2.start();//thread1.join();for (int i = 0; i < 80; i++) {System.out.println("mian "+i);}System.out.println("mina over");}}class JoinDmeo implements Runnable{public void run() {for (int i = 0; i < 70; i++) {System.out.println(Thread.currentThread().toString()+"--- run"+i);Thread.yield();//  释放执行权}}}

7  使用多线程的情景简单示例

package day12Thread;/**/public class ThreadTest {public static void main(String[] args) {new Thread(){public void run(){for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"------"+i);}}}.start();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"------"+i);}Runnable runnable=new Runnable() {@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"------"+i);}}};new Thread(runnable).start();}}//class Test1 extends Thread{//public void run() {//for (int i = 0; i < 100; i++) {//System.out.println(Thread.currentThread().getName()+"------"+i);//}//}//}

《传智播客_毕向东_Java基础视频教程\黑马程序员_毕向东_Java基础视频教程第12天 多线程 通信 优化 jdk 1.5 之后新特性Lock》

该天内容介绍了java 多线程中 的多线程通信机制,线程间唤醒、中断、同步机制,

学习了java中多线程的具体实现操作。


0 0
原创粉丝点击