并发程序具有制约性的特点,多线程之间需要进行同步与互斥,而锁与信号量是同步互斥操作的基础。
本章呢就结合代码主要将2种互斥锁与2种信号量。
2种锁&2信号量
2种锁
即synchronized关键字和lock,两种均可提供共享资源的互斥访问。
synchronized关键字和lock
- 1:synchronized是Java关键字,而Lock是锁对象。
- 2:synchronized可以使用任意对象、类进行互斥访问控制;Lock只能使用锁对象本身(基于AbstractQueuedSynchronizer接口(AQS))
- 3:lock相对synchronized来说更灵活,伸缩性更强,有利于提高并发性。
- 4:但是推荐使用synchronized,理由是更安全,更通用,更方便!
锁机制代码
public static void main(String[] args)
{
Share share=new Share();
for(int i = 0;i<10;i++)
{
Thread t1=new Thread(new MyRunnable(share),"t1");
t1.start();
}
}
public static class Share
{
private int num=100;
public int getnum()
{
return num;
}
public synchronized void decnum()
{
int num2=num;
num2-=10;
try {
Thread.sleep(1);// do something
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num=num2;
}
}
public static class MyRunnable implements Runnable
{
Share share;
public MyRunnable(Share share) {
this.share=share;
}
@Override
public void run() {
share.decnum();
System.out.println(share.getnum());
}
}
lock锁的实例与使用:
Lock lcok = new ReentrantLock();
lock.lock();
Thread.sleep(1000);
lock.unlock();
2种信号量
2种均是Semaphore 类只不过初始值不同,就表现出了不同的意义。
-
Semaphore(5)//信号量初始值为5 主要用于同步
-
Semaphore(1)//信号量初始值为1 可用于互斥
信号量的申请与使用源代码:
Semaphore semp = new Semaphore(5);//容量为5的信号量
semp.acquire();// 申请信号量
Thread.sleep((long) (Math.random() * 10000));
semp.release();// 释放信号量
信号量的详细使用,可以参考下一章的同步模型的源代码
上一章: 线程调度的6+6
下一章: 同步互斥及模型实现