Java多线程指定资源可以被多少个线程同时访问

通常情况下对公共资源指定可被多少个线程访问,通过设置同时允许访问的线程个数,每被一个线程访问,将该变量减一,当变量小于等于0时调用wait函数等待。一个线程访问资源结束后将变量加一,同时通知因wait而阻塞的线程。

下面模拟办理业务时只有5个窗口,每一个窗口同时只能接待一位客户,一位客户办理完成后才能办理下一位客户。
方法一:

public class ThreadDemo2 {
    final public static int total=10;
    public static void main(String args[]) {
        Runnable customer = new Runnable() {
            volatile int avaliableThread = 5;
            volatile int count = 0;
            public void run() {
                int time = (int) (Math.random() * 10 + 3);
                int num;
                synchronized (this) {
                    while (avaliableThread <= 0) {
                        try {
                            wait();//允许访问的线程个数小于等于0时,等待
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    avaliableThread--;
                    num=++count;
                }

                try {
                    System.out.println("正在为" + num + "办理业务,需要" + time + "s");
                    Thread.sleep(time * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (this) {
                    avaliableThread++;

                    if (avaliableThread > 0 && count < total) {
                        System.out.println("第" + num + "办理完业务,有请下一位!");
                        notify();//允许访问的线程个数大于0时,并且还有客户,通知等待的线程
                    } else {
                        System.out.println("第" + num + "办理完业务,没客户了,休息中!");
                    }
                }

            }
        };
        for (int i = 0; i < total; i++) {
            new Thread(customer).start();
        }
    }
}

方法二:
也可以采用JDK5中java.util.concurrent包引入的Semaphore解决。

package amazingtest;

import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
    public static void main(String args[]){
        Runnable customer=new Runnable() {
            final Semaphore semaphore=new Semaphore(5, true);
            volatile int count=1;
            public void run() {
                int time=(int) (Math.random()*10+3);
                int num=count++;
                try {
                    semaphore.acquire();
                    System.out.println("正在为"+num+"办理业务,需要"+time+"s");
                    Thread.sleep(time*1000);
                    if(semaphore.hasQueuedThreads()){
                        System.out.println("第"+num+"办理完业务,有请下一位!");
                    }else{
                        System.out.println("第"+num+"办理完业务,没客户了,休息中!");
                    }
                    semaphore.release();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        };
        for(int i=0;i<10;i++){
            new Thread(customer).start();
        }
    }
}

打印输出

正在为2办理业务,需要3s
正在为3办理业务,需要8s
正在为5办理业务,需要4s
正在为1办理业务,需要10s
正在为4办理业务,需要12s
第2办理完业务,有请下一位!
正在为7办理业务,需要11s
第5办理完业务,有请下一位!
正在为6办理业务,需要4s
第6办理完业务,有请下一位!3办理完业务,有请下一位!
正在为8办理业务,需要12s
正在为9办理业务,需要7s
第1办理完业务,有请下一位!
正在为10办理业务,需要8s
第4办理完业务,没客户了,休息中!7办理完业务,没客户了,休息中!9办理完业务,没客户了,休息中!10办理完业务,没客户了,休息中!8办理完业务,没客户了,休息中!

猜你喜欢

转载自blog.csdn.net/u011928958/article/details/77155194