并发核心框架:1.Semphore和Exchanger

Semphore的主要作用是控制线程并发的数量
Exchanger可以使两个线程之间方便的进行通信

1.Semphore的使用

该类的主要作用是限制并发的数量,如果不限制并发数量,则cpu的资源很快被耗尽,cpu需要把时间片分给不同的线程对象,而且上下文切换也要消耗时间,最终造成系统运行效率降低,所以限制并发数量是很有必要的

1.1Semphore的同步性

构造参数,permits代表许可的意思,代表同一时间内,最多允许多少个线程执行acquire和release之间的代码

public class Service {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName()
                    + " begin timer=" + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName()
                    + "   end timer=" + System.currentTimeMillis());
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class ThreadC extends Thread {

    private Service service;

    public ThreadC(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        ThreadB b = new ThreadB(service);
        b.setName("B");
        ThreadC c = new ThreadC(service);
        c.setName("C");
        a.start();
        b.start();
        c.start();
    }

}

运行结果:

1.2Semphore类构造方法中参数permits的作用

修改上面的代码

public class Service {

    private Semaphore semaphore = new Semaphore(2);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName()
                    + " begin timer=" + System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName()
                    + "   end timer=" + System.currentTimeMillis());
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}
运行结果;
A begin timer=1473079714988
B begin timer=1473079714988
B   end timer=1473079719988
A   end timer=1473079719988
C begin timer=1473079719988
C   end timer=1473079724989

1.3acquire(int permits)参数作用以及动态添加permits许可数量

acquire(permits)每次调用一次该方法,就使用x个许可
一共有十个许可,每次执行acquire(2)代码消耗掉两个,所以同一时间只有5个线程执行acquire和release之间的代码

public class Service {

    private Semaphore semaphore = new Semaphore(10);

    public void testMethod() {
        try {
            semaphore.acquire(2);
            System.out.println(Thread.currentThread().getName()
                    + " begin timer=" + System.currentTimeMillis());
            int sleepValue = ((int) (Math.random() * 10000));
            System.out.println(Thread.currentThread().getName() + " 停止了"
                    + (sleepValue / 1000) + "秒");
            Thread.sleep(sleepValue);
            System.out.println(Thread.currentThread().getName()
                    + "   end timer=" + System.currentTimeMillis());
            semaphore.release(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class Run {

    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();

        ThreadA[] a = new ThreadA[10];
        for (int i = 0; i < 10; i++) {
            a[i] = new ThreadA(service);
            a[i].start();
        } 
    } 
}
运行效果:
Thread-0 begin timer=1473080061065
Thread-0 停止了4秒
Thread-4 begin timer=1473080061067
Thread-4 停止了1秒
Thread-8 begin timer=1473080061067
Thread-8 停止了6秒
Thread-1 begin timer=1473080061067
Thread-1 停止了6秒
Thread-7 begin timer=1473080061067
Thread-7 停止了7秒
Thread-4   end timer=1473080062290
Thread-3 begin timer=1473080062290
Thread-3 停止了2秒
Thread-3   end timer=1473080064992
Thread-2 begin timer=1473080064992
Thread-2 停止了8秒
Thread-0   end timer=1473080065180
Thread-5 begin timer=1473080065180
Thread-5 停止了6秒
Thread-1   end timer=1473080068004
Thread-6 begin timer=1473080068004
Thread-6 停止了9秒
Thread-8   end timer=1473080068058
Thread-9 begin timer=1473080068058
Thread-9 停止了7秒
Thread-7   end timer=1473080068833
Thread-5   end timer=1473080071991
Thread-2   end timer=1473080073296
Thread-9   end timer=1473080075763
Thread-6   end timer=1473080077158

添加permits

public class Run {

    public static void main(String[] args) {
        try {
            Semaphore semaphore = new Semaphore(5);
            semaphore.acquire();
            semaphore.acquire();
            semaphore.acquire();
            semaphore.acquire();
            semaphore.acquire();
            System.out.println(semaphore.availablePermits());
            semaphore.release();
            semaphore.release();
            semaphore.release();
            semaphore.release();
            semaphore.release();
            semaphore.release();
            System.out.println(semaphore.availablePermits());
            semaphore.release(4);
            System.out.println(semaphore.availablePermits());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } 
    } 
}

运行结果:
0
6
10

1.4acquireUninterruptibly的使用

该方法的作用是:等待进入acquire的线程不允许被中断


public class Service {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out.println(Thread.currentThread().getName()
                    + " begin timer=" + System.currentTimeMillis());
            for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
                String newString = new String();
                Math.random();
            }
            System.out.println(Thread.currentThread().getName()
                    + "   end timer=" + System.currentTimeMillis());
            semaphore.release();
        } catch (InterruptedException e) {
            System.out.println("线程" + Thread.currentThread().getName()
                    + "进入了catch");
            e.printStackTrace();
        }
    }  
}

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class Run {

    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

        Thread.sleep(1000);

        b.interrupt();
        System.out.println("main中断了b");
    }

}

运行结果:
A begin timer=1473080486599
线程B进入了catch
main中断了b
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(Unknown Source)
    at java.util.concurrent.Semaphore.acquire(Unknown Source)
    at service.Service.testMethod(Service.java:11)
    at extthread.ThreadB.run(ThreadB.java:16)
A   end timer=1473080487812

public class Service {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        semaphore.acquireUninterruptibly();
        System.out.println(Thread.currentThread().getName() + " begin timer="
                + System.currentTimeMillis());
        for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
            String newString = new String();
            Math.random();
        }
        System.out.println(Thread.currentThread().getName() + "   end timer="
                + System.currentTimeMillis());
        semaphore.release();
    } 
}

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class Run {

    public static void main(String[] args) throws InterruptedException {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

        Thread.sleep(1000);

        b.interrupt();
        System.out.println("main中断了b");
    }

}

运行结果:
A begin timer=1473080684396
main中断了b
A   end timer=1473080685591
B begin timer=1473080685591
B   end timer=1473080686770


1.5 availablePermits,drainPermits方法

availablePermits获取当前可用的许可数
drainPermits获取并返回可用的许可数,并将可用许可置为0

public class MyService {

    private Semaphore semaphore = new Semaphore(10);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out.println(semaphore.availablePermits());
            System.out.println(semaphore.availablePermits());
            System.out.println(semaphore.availablePermits());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }

}


public class Run {

    public static void main(String[] args) {
        MyService service = new MyService();
        service.testMethod(); 
    } 
}

运行结果:
9
9
9

public class MyService {

    private Semaphore semaphore = new Semaphore(10);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out.println(semaphore.availablePermits());
            System.out.println(semaphore.drainPermits() + " "
                    + semaphore.availablePermits());
            System.out.println(semaphore.drainPermits() + " "
                    + semaphore.availablePermits());
            System.out.println(semaphore.drainPermits() + " "
                    + semaphore.availablePermits());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }

}


public class Run {

    public static void main(String[] args) {
        MyService service = new MyService();
        service.testMethod();

    }

}
运行结果:
9
9 0
0 0
0 0

1.6 getQueueLength和hasQueuedThreads

getQueueLength获取等待许可的线程个数
hasQueuedThreads判断有没有线程在等待这个许可


public class MyService {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        try {
            semaphore.acquire();
            Thread.sleep(1000);
            System.out.println("还有大约" + semaphore.getQueueLength() + "个线程在等待");
            System.out.println("是否有线程正在等待信号量呢?" + semaphore.hasQueuedThreads());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    } 
}


public class MyThread extends Thread {

    private MyService myService;

    public MyThread(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        myService.testMethod();
    }

}

public class Run {

    public static void main(String[] args) {
        MyService service = new MyService();

        MyThread firstThread = new MyThread(service);
        firstThread.start();

        MyThread[] threadArray = new MyThread[4];
        for (int i = 0; i < 4; i++) {
            threadArray[i] = new MyThread(service);
            threadArray[i].start();
        }

    }

}
运行结果:
还有大约4个线程在等待
是否有线程正在等待信号量呢?true
还有大约3个线程在等待
是否有线程正在等待信号量呢?true
还有大约2个线程在等待
是否有线程正在等待信号量呢?true
还有大约1个线程在等待
是否有线程正在等待信号量呢?true
还有大约0个线程在等待
是否有线程正在等待信号量呢?false

1.7 公平与非公平信号量测试

public class MyService {

    private boolean isFair = true;
    private Semaphore semaphore = new Semaphore(1, isFair);

    public void testMethod() {
        try {
            semaphore.acquire();
            System.out
                    .println("ThreadName=" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }

}


public class MyThread extends Thread {

    private MyService myService;

    public MyThread(MyService myService) {
        super();
        this.myService = myService;
    }

    @Override
    public void run() {
        System.out.println("ThreadName=" + this.getName() + "启动了!");
        myService.testMethod();
    }

}


public class Run {

    public static void main(String[] args) {
        MyService service = new MyService();

        MyThread firstThread = new MyThread(service);
        firstThread.start();

        MyThread[] threadArray = new MyThread[4];
        for (int i = 0; i < 4; i++) {
            threadArray[i] = new MyThread(service);
            threadArray[i].start();
        }

    }

}
运行结果:
ThreadName=Thread-0启动了!
ThreadName=Thread-0
ThreadName=Thread-2启动了!
ThreadName=Thread-2
ThreadName=Thread-1启动了!
ThreadName=Thread-3启动了!
ThreadName=Thread-1
ThreadName=Thread-3
ThreadName=Thread-4启动了!
ThreadName=Thread-4
改为false运行结果:
ThreadName=Thread-0启动了!
ThreadName=Thread-1启动了!
ThreadName=Thread-1
ThreadName=Thread-2启动了!
ThreadName=Thread-2
ThreadName=Thread-0
ThreadName=Thread-3启动了!
ThreadName=Thread-3
ThreadName=Thread-4启动了!
ThreadName=Thread-4

1.8tryAcquire方法

尝试获取允许,如果获取不到返回false,此方法的特点是不阻塞

public class Service {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        if (semaphore.tryAcquire()) {
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "首选进入!");
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                String newString = new String();
                Math.random();
            }
            semaphore.release();
        } else {
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "未成功进入!");
        }
    }
}

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }

}
运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!

1.9tryAcquire(permits)的用法

尝试获取x个允许,获取不到返回false

public class Service {

    private Semaphore semaphore = new Semaphore(3);

    public void testMethod() {
        if (semaphore.tryAcquire(3)) {
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "首选进入!");
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                String newString = new String();
                Math.random();
            }
            // 方法release对应的permits值也要更改
            semaphore.release(3);
        } else {
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "未成功进入!");
        }

    }
}



public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}

public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }

}
运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!

1.10tryAcquire(timeout,timeunit)

在指定时间内获取到一个许可,如果获取不到返回false

public class Service {

    private Semaphore semaphore = new Semaphore(1);

    public void testMethod() {
        try {
            if (semaphore.tryAcquire(3, TimeUnit.SECONDS)) {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName() + "首选进入!");
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
//                   String newString = new String();
//                   Math.random();
                }
                semaphore.release();
            } else {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName() + "未成功进入!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }

}
运行结果:
ThreadName=A首选进入!
ThreadName=B首选进入!
打开注释运行结果:
ThreadName=A首选进入!
ThreadName=B未成功进入!

1.11 tryAcquire(permits,timeout,timeunit)

在指定时间内获取x个许可,获取不到返回false

public class Service {

    private Semaphore semaphore = new Semaphore(3);

    public void testMethod() {
        // 1改成3
        try {
            if (semaphore.tryAcquire(3, 3, TimeUnit.SECONDS)) {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName() + "首选进入!");
                for (int i = 0; i < Integer.MAX_VALUE; i++) {
                }
                // 方法release对应的permits值也要更改
                semaphore.release(3);
            } else {
                System.out.println("ThreadName="
                        + Thread.currentThread().getName() + "未成功进入!");
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.testMethod();
    }

}


public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();
        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();
    }

}
运行结果:
ThreadName=B首选进入!
ThreadName=A首选进入!

1.12多进路-多处理-多出路实验

public class Service {

    private Semaphore semaphore = new Semaphore(3);

    public void sayHello() {
        try {
            semaphore.acquire();
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "准备");
            System.out.println("begin hello " + System.currentTimeMillis());
            for (int i = 0; i < 3; i++) {
                System.out.println(Thread.currentThread().getName() + "打印"
                        + (i + 1));
                Thread.sleep(1000);
            }
            System.out.println("  end hello " + System.currentTimeMillis());
            semaphore.release();
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class MyThread extends Thread {

    private Service service;

    public MyThread(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.sayHello();
    }

}
public class Run {

    public static void main(String[] args) {
        Service service = new Service();

        MyThread[] threadArray = new MyThread[6];
        for (int i = 0; i < threadArray.length; i++) {
            threadArray[i] = new MyThread(service);
            threadArray[i].start();
        }
    }

}

运行结果:
ThreadName=Thread-1准备
begin hello 1473336081756
Thread-1打印1
ThreadName=Thread-2准备
begin hello 1473336081756
Thread-2打印1
ThreadName=Thread-0准备
begin hello 1473336081756
Thread-0打印1
Thread-2打印2
Thread-0打印2
Thread-1打印2
Thread-2打印3
Thread-1打印3
Thread-0打印3
  end hello 1473336084774
  end hello 1473336084774
ThreadName=Thread-1结束
  end hello 1473336084774
ThreadName=Thread-3准备
ThreadName=Thread-4准备
begin hello 1473336084774
Thread-4打印1
ThreadName=Thread-5准备
begin hello 1473336084774
Thread-5打印1
ThreadName=Thread-0结束
begin hello 1473336084774
Thread-3打印1
ThreadName=Thread-2结束
Thread-3打印2
Thread-4打印2
Thread-5打印2
Thread-3打印3
Thread-5打印3
Thread-4打印3
  end hello 1473336087785
ThreadName=Thread-5结束
  end hello 1473336087785
ThreadName=Thread-4结束
  end hello 1473336087785
ThreadName=Thread-3结束


1.13多进路-单处理-多出路实验

public class Service {

    private Semaphore semaphore = new Semaphore(3);
    private ReentrantLock lock = new ReentrantLock();

    public void sayHello() {
        try {
            semaphore.acquire();
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "准备");
            lock.lock();
            System.out.println("begin hello " + System.currentTimeMillis());
            for (int i = 0; i < 3; i++) {
                System.out.println(Thread.currentThread().getName() + "打印"
                        + (i + 1));
                Thread.sleep(1000);
            }
            System.out.println(Thread.currentThread().getName()+"  end hello ");
            lock.unlock();
            semaphore.release();
            System.out.println("ThreadName=" + Thread.currentThread().getName()
                    + "结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class MyThread extends Thread {

    private Service service;

    public MyThread(Service service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.sayHello();
    }

}

public class Run {

    public static void main(String[] args) {
        Service service = new Service();

        MyThread[] threadArray = new MyThread[6];
        for (int i = 0; i < threadArray.length; i++) {
            threadArray[i] = new MyThread(service);
            threadArray[i].start();
        }
    }

}
ThreadName=Thread-0准备
begin hello 1473336405058
Thread-0打印1
ThreadName=Thread-2准备
ThreadName=Thread-1准备
Thread-0打印2
Thread-0打印3
Thread-0  end hello 
begin hello 1473336408060
Thread-2打印1
ThreadName=Thread-3准备
ThreadName=Thread-0结束
Thread-2打印2
Thread-2打印3
Thread-2  end hello 
ThreadName=Thread-2结束
begin hello 1473336411070
Thread-1打印1
ThreadName=Thread-4准备
Thread-1打印2
Thread-1打印3
Thread-1  end hello 
ThreadName=Thread-5准备
begin hello 1473336414074
ThreadName=Thread-1结束
Thread-3打印1
Thread-3打印2
Thread-3打印3
Thread-3  end hello 
ThreadName=Thread-3结束
begin hello 1473336417077
Thread-4打印1
Thread-4打印2
Thread-4打印3
Thread-4  end hello 
ThreadName=Thread-4结束
begin hello 1473336420089
Thread-5打印1
Thread-5打印2
Thread-5打印3
Thread-5  end hello 
ThreadName=Thread-5结束

1.14使用Semphore创建字符串池

public class ListPool {

    private int poolMaxSize = 5;
    private int semaphorePermits = 5;
    private List list = new ArrayList();
    private Semaphore concurrencySemaphore = new Semaphore(semaphorePermits);
    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public ListPool() {
        super();
        for (int i = 0; i < poolMaxSize; i++) {
            list.add("高洪岩" + (i + 1));
        }
    }

    public String get() {
        String getString = null;
        try {
            concurrencySemaphore.acquire();
            lock.lock();
            while (list.size() == 0) {
                condition.await();
            }
            getString = list.remove(0);
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return getString;
    }

    public void put(String stringValue) {
        lock.lock();
        list.add(stringValue);
        condition.signalAll();
        lock.unlock();
        concurrencySemaphore.release();
    }

}

public class MyThread extends Thread {

    private ListPool listPool;

    public MyThread(ListPool listPool) {
        super();
        this.listPool = listPool;
    }

    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String getString = listPool.get();
            System.out.println(Thread.currentThread().getName() + " 取得值 "
                    + getString);
            listPool.put(getString);
        }
    }

}

 
public class Run {

    public static void main(String[] args) {

        ListPool pool = new ListPool();

        MyThread[] threadArray = new MyThread[12];
        for (int i = 0; i < threadArray.length; i++) {
            threadArray[i] = new MyThread(pool);
        }
        for (int i = 0; i < threadArray.length; i++) {
            threadArray[i].start();
        }

    }
}

运行结果:


1.15使用Semphore实现生产者消费者模式


public class RepastService {

    volatile private Semaphore setSemaphore = new Semaphore(10);// 厨师
    volatile private Semaphore getSemaphore = new Semaphore(20);// 就餐者
    volatile private ReentrantLock lock = new ReentrantLock();
    volatile private Condition setCondition = lock.newCondition();
    volatile private Condition getCondition = lock.newCondition();
    volatile private Object[] producePosition = new Object[4];

    private boolean isEmpty() {
        boolean isEmpty = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] != null) {
                isEmpty = false;
                break;
            }
        }
        if (isEmpty == true) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isFull() {
        boolean isFull = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] == null) {
                isFull = false;
                break;
            }
        }
        return isFull;
    }

    public void set() {
        try {
            // System.out.println("set");
            setSemaphore.acquire();// 允许同时最多有10个厨师进行生产
            lock.lock();
            while (isFull()) {
                // System.out.println("生产者在等待");
                setCondition.await();
            }
            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] == null) {
                    producePosition[i] = "数据";
                    System.out.println(Thread.currentThread().getName()
                            + " 生产了 " + producePosition[i]);
                    break;
                }
            }
            getCondition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            setSemaphore.release();
        }
    }

    public void get() {
        try {
            // System.out.println("get");
            getSemaphore.acquire();// 允许同时最多有16个就餐者
            lock.lock();
            while (isEmpty()) {
                // System.out.println("消费者在等待");
                getCondition.await();
            }
            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] != null) {
                    System.out.println(Thread.currentThread().getName()
                            + " 消费了 " + producePosition[i]);
                    producePosition[i] = null;
                    break;
                }
            }
            setCondition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            getSemaphore.release();
        }
    }

}

public class ThreadP extends Thread {

    private RepastService service;

    public ThreadP(RepastService service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.set();
    }

}

public class ThreadC extends Thread {

    private RepastService service;

    public ThreadC(RepastService service) {
        super();
        this.service = service;
    }

    @Override
    public void run() {
        service.get();
    }

}

public class Run {

    public static void main(String[] args) throws InterruptedException {
        RepastService service = new RepastService();
        ThreadP[] arrayP = new ThreadP[60];
        ThreadC[] arrayC = new ThreadC[60];
        for (int i = 0; i < 60; i++) {
            arrayP[i] = new ThreadP(service);
            arrayC[i] = new ThreadC(service);
        }
        Thread.sleep(2000);
        for (int i = 0; i < 60; i++) {
            arrayP[i].start();
            arrayC[i].start();
        }
    }

}

2.Exchanger的使用

两个线程之间传输数据,比wait/notify更方便

2.1exchange方法阻塞的特性

exchange方法调用后等待其他线程来取得数据,如果没有其他线程来取数据,就一直阻塞等待

public class ThreadA extends Thread {

    private Exchanger exchanger;

    public ThreadA(Exchanger exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        try {
            System.out.println("在线程A中得到线程B的值=" + exchanger.exchange("中国人A"));
            System.out.println("A end!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } 
}

public class Run {
    public static void main(String[] args) {
        Exchanger exchanger = new Exchanger();
        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }

}
运行结果:A线程一直等待
main end!

2.2方法exchange()传递数据

public class ThreadA extends Thread {

    private Exchanger exchanger;

    public ThreadA(Exchanger exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        try {
            System.out.println("在线程A中得到线程B的值=" + exchanger.exchange("中国人A"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public class ThreadB extends Thread {

    private Exchanger exchanger;

    public ThreadB(Exchanger exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        try {
            System.out.println("在线程B中得到线程A的值=" + exchanger.exchange("中国人B"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

public class Run {
    public static void main(String[] args) {
        Exchanger exchanger = new Exchanger();
        ThreadA a = new ThreadA(exchanger);
        ThreadB b = new ThreadB(exchanger);
        a.start();
        b.start();
    }

}
运行结果: 
在线程B中得到线程A的值=中国人A
在线程A中得到线程B的值=中国人B 

2.3exchange(data,timeout,timeuit);

指定时间内没有线程来获取数据就抛异常

public class ThreadA extends Thread {

    private Exchanger exchanger;

    public ThreadA(Exchanger exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        try {
            System.out.println("在线程A中得到线程B的值="
                    + exchanger.exchange("中国人A", 5, TimeUnit.SECONDS));
            System.out.println("A end!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }

}

public class Run {
    public static void main(String[] args) {
        Exchanger exchanger = new Exchanger();
        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }

}

运行结果:
main end!
java.util.concurrent.TimeoutException
    at java.util.concurrent.Exchanger.exchange(Unknown Source)
    at extthread.ThreadA.run(ThreadA.java:20)

你可能感兴趣的:(并发核心框架:1.Semphore和Exchanger)