《LINUX实战:各种同步控制工具的使用》要点:
本文介绍了LINUX实战:各种同步控制工具的使用,希望对您有用。如果有疑问,可以联系我们。
共享锁,运行多个线程同时临界区
public void acquire()
public void acquireUninterruptibly()
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public void release()
public class SemaphoreDemo {
private static final int THREAD_COUNT = 3;
private static ExecutorService threadPool = Executors
.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(1);
public static void main(String[] args) {
for(int i=0;i<3;i++)
{
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"start data");
Thread.sleep(2000);
s.acquire();
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"save data");
s.release();
System.out.println(Thread.currentThread().getName()+"release data");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+"end data");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
threadPool.shutdown();
}
}最后得出一个比较有意思的结论:Semaphore 像是一个共享的屋子,这个屋子里面只能有一定的人数,这个人数是所有人可以看到的,甚至与release()这个办法,可以被别的线程进行调用,
一般使用acquire() 与release() 这个之间的代码只能有固定数量的线程存在,当然这种是当火线程进行获取和释放
ReadWriteLock是JDK5中提供的读写分别锁
private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
这个类如果没有写锁的情况下,读是无阻塞的,在必定程度上提高了程序的执行效率.
public void run() {
//isRead自界说变量(判断这个线程是读还是写)
if (isRead) {
//获取读锁
myLock.readLock().lock();
System.out.println("读");
//释放读锁
myLock.readLock().unlock();
} else {
//获取写锁
myLock.writeLock().lock();
//执行现金业务
System.out.println("写");
//释放写锁
myLock.writeLock().unlock();
}
}

static final CountDownLatch end = new CountDownLatch(10);
end.countDown(); //这个办法是子线程作完作业之后,调用的
end.await(); //主线等待指定数量的子线程完成作业,当所有子线程完成之后,主线程自动激活执行
public class CountDownLatchDemo {
private static CountDownLatch countDownLatch=new CountDownLatch(10);
public static void main(String[] args) {
for(int i=0;i<10;i++)
{
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"work");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
}
}).start();
}
new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
System.out.println(Thread.currentThread().getName()+"主线程start");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"main1").start();
}
}
public class CyclicBarrierDemo {
public static class Soldier implements Runnable{
private String name;
private final CyclicBarrier cyclicBarrier;
public Soldier(String name,CyclicBarrier c) {
this.name = name;
this.cyclicBarrier=c;
}
@Override
public void run() {
try{
//等待所有士兵到齐
System.out.println(name +"报道");
cyclicBarrier.await();
dowork();
//等待所有士兵完成工作
cyclicBarrier.await();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void dowork()
{
System.out.println(name +"完成任务");
}
}
public static class BarrierRun implements Runnable{
boolean flag;
int number;
public BarrierRun(boolean flag, int number) {
this.flag = flag;
this.number = number;
}
@Override
public void run() {
if(!flag)
{
System.out.println("士兵集合完毕");
flag=true;
System.out.println("开始执行任务");
}
else{
System.out.println("任务完成");
}
}
}
public static void main(String[] args) {
final int N =10;
CyclicBarrier barrier =new CyclicBarrier(N,new BarrierRun(false,N));
System.out.println("集合队伍");
for(int i=0;i<N;i++)
{
new Thread(new Soldier("士兵"+i,barrier)).start();
}
}
}每次CyclicBarrier 调用await()办法之后,都会等待所有的子线程,之后执行CyclicBarrier 的Runnable的办法
unpark函数可以先于park调用.好比线程B调用unpark函数,给线程A发了一个“许可”,那么当线程A调用park时,它发现已经有“许可”了,那么它会马上再继续运行.
上面已经提到,unpark函数可以先于park挪用,这个正是它们的灵活之处.
一个线程它有可能在别的线程unPark之前,或者之后,或者同时调用了park,那么因为park的特性,它可以不用担心本身的park的时序问题
本文永远更新链接地址:
欢迎参与《LINUX实战:各种同步控制工具的使用》讨论,分享您的想法,维易PHP学院为您提供专业教程。