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

互斥锁和信号量都是操作系统中为并发编程设计基本概念,互斥锁和信号量的概念上的不同在于,对于同一个资源,互斥锁只有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 {

@Override
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值