java学习第十三天多线程的死锁和并发

来源:互联网 发布:it到dt是什么意思 编辑:程序博客网 时间:2024/06/10 04:14
package MoreThreadLearn;import java.util.Set;/*多线程间的通信,多个线程都在处理同一个资源,但是处理的任务却不一样生产者,消费者通过同步,解决了没生产就消费的问题但是出现了连续的生产没有消费的情况,和需求生产一个,消费一个的情况不符使用了等待唤醒机制wait();//该方法可以让线程处于冻结状态,并将线程临时存储到线程池中国notify();//唤醒指定线程池中的任意一个线程notifyAll();//唤醒指定线程池中的所有线程这些方法必须使用在同步中,因为它们又来操作同步锁上的现成的状态的在使用这些方法时,必须标识它们所属于的锁,标识方式就是  锁对象.wait();   锁对象.notify();    锁对象.notifyAll();相同锁的notify(),可以获取相同锁的wait();*//*多生产多消费问题1:    重复生产,重复消费    原因:经过复杂的(等、资格)分析,发现被唤醒的线程没有判断标记就开始工作了(生成或消费)    导致了重复的生成和消费的发生    解决:    那就是被唤醒的线程必须判断标记    使用while循环搞定问题2:    死锁了 。所有的线程都处于冻结状态    原因:本方线程在唤醒时,又一次唤醒了本方线程。而本方线程循环判断标记,又继续等待    而导致所有的线程都等待了    解决:    希望本方如果唤醒了对方线程,就可以解决    可以使用notifyAll()方法    那不是全唤醒了吗?是的,既有本方又有对方。但是本方醒后,会判断标记继续等待    这样对方就有线程可以执行了*/public class ProduceConsumerDemo {    public static void main(String[] args) {//      创建资源        Res res=new Res();//      创建两个任务        Producer producer=new Producer(res);        Customers customers=new Customers(res);        Thread t1=new Thread(producer);        Thread t2=new Thread(customers);        t1.start();        t2.start();    }}//描述资源class Res{    private String name;    private int count=1;    //定义标记    private boolean flag;    //提供给商品赋值的方法    public synchronized void set(String name){              if(flag)//判断标记为true,执行wait,为false,就生产            try {            wait();                 } catch (InterruptedException e) {}                     this.name = name +"--"+count;        count++;        System.out.println(Thread.currentThread().getName()+"...生产者....."+this.name);        //生产完毕,将标记改为notify()        flag=true;        //唤醒消费者        notify();    }//  提供一个获取商品的方法    public synchronized void get() {                if(!flag)            try {                wait();                     } catch (InterruptedException e) {}         System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);        //将标记改为false        flag=false;        //唤醒消费者        notify();    }}//生产者class Producer implements Runnable{    private Res res;    public Producer(Res res) {        this.res=res;    }    public void run(){        while(true){            res.set("面包");                  }           }}//消费者class Customers implements Runnable{    private Res res;    public Customers(Res res) {    this.res=res;    }    public void run(){        while(true){            res.get();        }           }}

package MoreThreadLearn;import java.util.concurrent.locks.*;/*解决了多生产多消费的效率问题使用了JDK1.5 java.util.concurrent.locks包中的对象lock接口:它的出现比synchronized有更多的操作    lock():获取锁    unlock():释放锁同步代码块或者同步函数的锁的操作是隐式 的JDK1.5  Lock接口,按照面向对象的思想,将锁单独封装成一个对象,并提供了对锁的显示操作Lock接口就是同步的替代1、将线程中的同步更换为Lock接口的形式替换完运行失败了,因为wait没有同步区域,没有了所属的同步锁同步升级了。其中锁已经不再是任意对象,而是Lock类型的对象那么和任意对象绑定的监视方法,是不是也升级了,有了专门的和Lock类型锁的绑定的监视机器方法呢?查阅api。Condition接口替代啦Object中的监视器方法以前监视器方法封装到每一个对象当中现在将监视器方法封装到Condition对象中方法名为:await signal signalAllobj作为锁,本身就是监视器方法监视器对象Condition如何和*//*wait()和 sleep()的区别?相同:可以让线程处于冻结状态不同点:    1、wait()可以指定时间。也可以不指定    sleep()必须指定时间    2、wait():释放资源,释放锁    sleep():释放cpu资源,不释放锁*//*synchronized(obj){    obj.wait();    code ....}Synchronized(obj){    obj.notifyAll();}*/public class ProducerCustomerThread {    public static void main(String[] args) {        Res res=new Res();        Producer producer=new Producer(res);        Consumer consumer=new Consumer(res);//      创建线程         Thread t1= new Thread(producer);          Thread t2 =new Thread(consumer);         t1.start();         t2.start();    }}class Res2{    private String name;    private int count=1;    private boolean flag;    private Lock lock=new ReentrantLock();    private Condition condition=lock.newCondition();    public void set(String name){        //获取锁        lock.lock();        try {            while (flag)                try {                    condition.await();                } catch (Exception e) {}            this.name=name+"--"+count;            count++;            System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);            flag=true;            condition.signalAll();        } finally {            //释放锁            lock.unlock();        }    }    public void get(){        lock.lock();        try {            while (!flag)//一定要记得用while判断                try {                    condition.await();                } catch (Exception e) {}            this.name=name+"--"+count;            count++;            System.out.println(Thread.currentThread().getName()+"...消费者..."+this.name);            flag=false;            condition.signalAll();//和while相对应的signalAll();           } finally {            //释放锁            lock.unlock();        }    }}class Consumer implements Runnable{    private Res res;    public Consumer(Res res) {        this.res=res;    }    public void run(){        while(true){            res.get();              }           }}class Producers implements Runnable{    private Res res;    public Producers(Res res) {    this.res=res;    }    public void run(){        while(true){            res.set("面包");          }           }}
0 0
原创粉丝点击