------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
黑马程序员 java 基础 毕向东 面向对象 多线程 通信 优化 jdk 1.5 之后新特性Lock
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(); } }
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(); } }
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(); } }
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(); } } }
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; } }
package day12Thread; /* * 当 A线程执行到了 B线程的Join方法时 * A线程就会等待B线程终止,A才会 执行 * join可以用来临时加入线程执行 * * Thread[Thread-0,5,main]--- run29 Thread[Thread-1,5,main]--- run32 Thread[Thread-0,5,main]--- run30 Thread【线程名,优先级,线程组】 一般谁开启了线程,线程属于哪个组 优先级 代表 使用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();// 释放执行权 } } }
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() { @Override public 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中多线程的具体实现操作。