线程初步(三)

来源:互联网 发布:淘宝怎么添加背景音乐 编辑:程序博客网 时间:2024/06/05 15:19

在jdk1.5中新加入锁的概念
同时还新增了condition方法
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
使用时
Lock xx=new (lock下的类)();
Condition xx = lock.newCondition();
xx.await() ;
xx.signal();
xx.signalAll();
我们先将上次的程序改写成现在的锁的程序

/** * 写一个商品者生产消费者消费的线程小程序 * @author lover * */import java.util.*;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class goods{    private int sum=1;    private String name;    boolean flag=false;    private Lock lock=new ReentrantLock();    private Condition con=lock.newCondition();    public  void set(String name){          lock.lock();        try{        while(flag){            try {                con.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        this.name=name+sum;        sum++;        System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);        flag=true;        con.signalAll();            }finally{        lock.unlock();    }}    public synchronized void out(){        lock.lock();        try{        while(!flag){            try {                con.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        System.out.println(Thread.currentThread().getName()+".......消费........"+this.name);        flag=false;        con.signalAll();        }finally{            lock.unlock();        }    }}class produce implements Runnable{    goods s;    public produce(goods s){        this.s=s;    }    public void run(){            while(true){                s.set("面包");            }    }}class customer implements Runnable{    goods s;    public customer(goods s){        this.s=s;    }    public void run(){        while(true){            s.out();        }    }}public class ShangPin {public static void main(String[] args) {    goods s=new goods();    produce t1=new produce(s);    produce t2=new produce(s);    customer t3=new customer(s);    customer t4=new customer(s);    Thread t11=new Thread(t1);    Thread t22=new Thread(t2);    Thread t33=new Thread(t3);    Thread t44=new Thread(t4);    t11.start();    t22.start();    t33.start();    t44.start();}}
现有的程序我们只能使用signalAll方法将所有的线程全部唤醒,这样降低了程序的性能现在我们的希望能在生产者的方法区里控制消费者线程的唤醒,并且在消费者的方法区里控制生产者线程的唤醒。我们再次进行改写程序
/** * 写一个商品者生产消费者消费的线程小程序 * @author lover * */import java.util.*;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class goods{    private int sum=1;    private String name;    boolean flag=false;    private Lock lock=new ReentrantLock();    **private Condition con1=lock.newCondition();    private Condition con2=lock.newCondition();**    public  void set(String name){          lock.lock();        try{        while(flag){            try {                con1.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        this.name=name+sum;        sum++;        System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);        flag=true;        con2.signal();          }finally{        lock.unlock();    }}    public synchronized void out(){        lock.lock();        try{        while(!flag){            try {                con2.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        System.out.println(Thread.currentThread().getName()+".......消费........"+this.name);        flag=false;        con1.signal();        }finally{            lock.unlock();        }    }}class produce implements Runnable{    goods s;    public produce(goods s){        this.s=s;    }    public void run(){            while(true){                s.set("面包");            }    }}class customer implements Runnable{    goods s;    public customer(goods s){        this.s=s;    }    public void run(){        while(true){            s.out();        }    }}public class ShangPin {public static void main(String[] args) {    goods s=new goods();    produce t1=new produce(s);    produce t2=new produce(s);    customer t3=new customer(s);    customer t4=new customer(s);    Thread t11=new Thread(t1);    Thread t22=new Thread(t2);    Thread t33=new Thread(t3);    Thread t44=new Thread(t4);    t11.start();    t22.start();    t33.start();    t44.start();}}

这次的程序,生产者与消费者使用同一个锁,单创建两个不同的监视器,一个为生产者的监视器,一个为消费者的监视器。这样我们就可以通过不同的监视器来唤醒所需要的线程。

在实际生产过程中,往往不是生产一个面包,而是一堆,我们可以通过创建一个数组来完成对操作代码如下:
/** * 写一个商品者生产消费者消费的线程小程序 * @author lover * */import java.util.*;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;class goods{    private int sum=1;int x=0;int y=0;    private String name;    final String[] items=new String[10];    private Lock lock=new ReentrantLock();    private Condition notfull=lock.newCondition();    private Condition notempty=lock.newCondition();    public  void set(String name){          lock.lock();        try{        while(items.length==sum){            try {                notfull.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        this.name=name;        items[x]=name+sum;        if(++x==items.length)            x=0;        ++sum;        System.out.println(Thread.currentThread().getName()+"....生产...."+items[x]+"............."+x);        notempty.signal();          }finally{        lock.unlock();    }}    public synchronized void out(){        lock.lock();        try{        while(sum==0){            try {                notempty.await();            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        String q=items[y];        System.out.println(Thread.currentThread().getName()+".......消费........"+items[y]+"...."+y);        if(++y==items.length)            y=0;        --sum;        notfull.signal();        }finally{            lock.unlock();        }    }}class produce implements Runnable{    goods s;    public produce(goods s){        this.s=s;    }    public void run(){            while(true){                s.set("面包");            }    }}class customer implements Runnable{    goods s;    public customer(goods s){        this.s=s;    }    public void run(){        while(true){            s.out();        }    }}public class ShangPin {public static void main(String[] args) {    goods s=new goods();    produce t1=new produce(s);    produce t2=new produce(s);    customer t3=new customer(s);    customer t4=new customer(s);    Thread t11=new Thread(t1);    Thread t22=new Thread(t2);    Thread t33=new Thread(t3);    Thread t44=new Thread(t4);    t11.start();    t22.start();    t33.start();    t44.start();}}

输出如下

Thread-1....生产....面包1.............6Thread-1....生产....面包2.............7Thread-1....生产....面包3.............8Thread-1....生产....面包4.............9Thread-1....生产....面包5.............0Thread-1....生产....面包6.............1Thread-1....生产....面包7.............2Thread-1....生产....面包8.............3Thread-1....生产....面包9.............4Thread-1....生产....面包0.............5Thread-3.......消费........面包1....6Thread-3.......消费........面包2....7Thread-3.......消费........面包3....8Thread-3.......消费........面包4....9Thread-3.......消费........面包5....0Thread-3.......消费........面包6....1Thread-3.......消费........面包7....2Thread-3.......消费........面包8....3Thread-3.......消费........面包9....4Thread-3.......消费........面包0....5
原创粉丝点击