java中的互斥锁,信号量和多线程等待机制

来源:互联网 发布:算法培训班 编辑:程序博客网 时间:2024/05/19 15:40
互斥锁和信号量都是操作系统中为并发编程设计基本概念,互斥锁和信号量的概念上的不同在于,对于同一个资源,互斥锁只有0和1 的概念,而信号量不止于此。也就是说,信号量可以使资源同时被多个线程访问,而互斥锁同时只能被一个线程访问。互斥锁在java中的实现就是 ReetranLock , 在访问一个同步资源时,它的对象需要通过方法 tryLock() 获得这个锁,如果失败,返回 false,成功返回true。根据返回的信息来判断是否要访问这个被同步的资源。
package com.thread;import java.util.concurrent.locks.ReentrantLock;public class ReentranLockExample {private static int count = 0;private static ReentrantLock reentrantLock = new ReentrantLock();static class MyThread extends Thread {@Overridepublic void run() {super.run();try {while (true) {boolean result = reentrantLock.tryLock();if (result) {System.out.println(Thread.currentThread().getName()+ "get the lock success and run the syn code " + count++);reentrantLock.unlock();} else {System.out.println(Thread.currentThread().getName() + "get the lock failed and run the syn code " + count);}System.out.println(Thread.currentThread().getName() + "run the asyntronized code  " + count);Thread.sleep(5000);}} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {MyThread thread1 = new MyThread();MyThread thread2 = new MyThread();thread1.start();thread2.start();}} 

信号量相当于一个计数器,如果线程想要访问某个资源,则先要获得这个资源的信号量,并且信号量内部的计数器减1 ,信号量内部的计数器大于0则意味着有可以使用的资源,当线程使用完某个资源时,必须释放这个资源的信号量。信号量的一个作用就是可以实现指定个线程去同事访问某个资源。只需要在初始化 。
信号量在 Java中的实现是 Semaphore ,其在初始化时传入一个整型数, 用来指定同步资源最大的并发访问量。

package com.thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;public class SemaphoreExample {    public static void main(String[] args) {        // 线程池        ExecutorService exec = Executors.newCachedThreadPool();        // 只能5个线程同时访问        final Semaphore semp = new Semaphore(5);        // 模拟20个客户端访问        for (int index = 0; index < 20; index++) {            final int NO = index;            Runnable run = new Runnable() {                public void run() {                    try {                        // 获取许可                        semp.acquire();                        System.out.println("Accessing: " + NO);                        Thread.sleep((long) (Math.random() * 10000));                        // 访问完后,释放                        semp.release();                        System.out.println("-----------------" + semp.availablePermits());                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            };            exec.execute(run);        }        // 退出线程池        exec.shutdown();    }}        CountDownLatch 实现一个等待机制,在诸如 等待与会者到达后,开始会议的使用中。ConutDownLatch 在初始化中一个计数器,用来指定需要等待的个数。在并发编程中,所解决的需求就是,等待所有的线程到达某个点后。才开始进行下一步,有点类似于开会,只有当所有的与会人员都到齐后,会议才能开始。

package com.thread;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
private static CountDownLatch mCountDownLatch = new CountDownLatch(3);

static class MyThread extends Thread {    int awaitTime;    public MyThread(int i) {        this.awaitTime = i;    }    @Override    public void run() {        super.run();        try {            Thread.sleep(awaitTime);            System.out.println(Thread.currentThread().getName() + "arrived ");            mCountDownLatch.countDown();            mCountDownLatch.await(); // 可以指定等待时间            System.out.println(Thread.currentThread().getName() + "start meeting ");        } catch (InterruptedException e) {            e.printStackTrace();        }    }}public static void main(String[] args) {    MyThread thread1 = new MyThread(500);    MyThread thread2 = new MyThread(1000);    MyThread thread3 = new MyThread(2000);    thread1.start();    thread2.start();    thread3.start();}

}

“`

0 0
原创粉丝点击