线程初步(三)

在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.............6
Thread-1....生产....面包2.............7
Thread-1....生产....面包3.............8
Thread-1....生产....面包4.............9
Thread-1....生产....面包5.............0
Thread-1....生产....面包6.............1
Thread-1....生产....面包7.............2
Thread-1....生产....面包8.............3
Thread-1....生产....面包9.............4
Thread-1....生产....面包0.............5
Thread-3.......消费........面包1....6
Thread-3.......消费........面包2....7
Thread-3.......消费........面包3....8
Thread-3.......消费........面包4....9
Thread-3.......消费........面包5....0
Thread-3.......消费........面包6....1
Thread-3.......消费........面包7....2
Thread-3.......消费........面包8....3
Thread-3.......消费........面包9....4
Thread-3.......消费........面包0....5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值