java多线程 信号量(Semaphore),死锁
来源:互联网 发布:库存盘点软件 编辑:程序博客网 时间:2024/04/29 16:30
信号量可以用来限制访问公共资源。在访问公共资源之前,线程必须从信号量获取许可。在访问资源之后,这个线程必须将许可返回给信号量,
为了创建信号量,必须使用可选的公平策略来确定许可的数量。任务通过调用信号量acquire() 方法来获得许可,可通过调用信号量的release()方法来释放许可。一旦获得许可,信号量中可用许可的数量减一。一旦许可呗释放掉,信号量的可用许可的总数加1。
使用只有一个许可的信号量可以模拟一个相互排斥的锁。
import java.util.concurrent.*;public class SemaphoreTest{private static Account _account = new Account();public static void main(String[] args) { ExecutorService executor = Executors.newCachedThreadPool(); for(int i=0; i<100;i++){executor.execute(new depositTask());} executor.shutdown(); while(!executor.isTerminated()){}System.out.println("任务完成");System.exit(0);}private static class depositTask implements Runnable{@Overridepublic void run(){_account.deposit(1);}}public static class Account{private static Semaphore _semaphore = new Semaphore(1,true);private int _menoeyy=0;private int GetMenoey(){return _menoeyy;}private void deposit(int monery){try{_semaphore.acquire();_menoeyy+=monery;Thread.sleep(50);System.out.println(getAccountInfo());}catch ( InterruptedException ex){} finally{ _semaphore.release();}} public String getAccountInfo(){return "当前账户与额为:¥"+_menoeyy;}}}
避免死锁
有时两个或者多个线程需要在一个共享对象上获取锁,这可能导致死锁(Deadlock),也就是说,每个线程已经锁定一个对象,而且正在等待另一个对象。下面是一个很可能造成死锁的例子
import java.util.concurrent.*;public class DeadlockTest {public static byte[] locker1 = new byte[0];public static byte[] locker2 = new byte[0];public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(100);for(int i =0 ;i <50;i++){executor.execute(new DeadlockTask1());executor.execute(new DeadlockTask2());}executor.shutdown();while(!executor.isTerminated()){}System.exit(0);}private static class DeadlockTask1 implements Runnable{public void run(){<span style="color: rgb(204, 0, 0);">synchronized(locker1){</span>System.out.println(" DeadlockTask1 获得锁 locker1 没有死锁!");<span style="color: rgb(204, 0, 0);">synchronized(locker2){</span>System.out.println(" DeadlockTask1 获得锁 locker2 没有死锁!");}}}}private static class DeadlockTask2 implements Runnable{public void run(){<span style="color: rgb(153, 0, 0);">synchronized(locker2){</span>System.out.println(" DeadlockTask2 获得锁 locker2 没有死锁!");<span style="color: rgb(153, 0, 0);">synchronized(locker1){</span>System.out.println(" DeadlockTask2 获得锁 locker1 没有死锁!");}}}}}
但是使用资源排序技术就可以轻易的避免死锁的发生。原理就是为每一个需要锁的对象排序,确保每个线程都按照这个顺序来获取锁。假设,按照locker1、locker2的顺序对连个对象排序。采用资源排序技术,线程2必须先获得locker1上的锁,然后才能获取lock2上面的锁。一旦线程1 获取的locker1上的锁,线程2必须等待locker1的锁。所以不会在发生死锁现象。
import java.util.concurrent.*;public class DeadlockTest {public static byte[] locker1 = new byte[0];public static byte[] locker2 = new byte[0];public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(100);for(int i =0 ;i <50;i++){executor.execute(new DeadlockTask1());executor.execute(new DeadlockTask2());}executor.shutdown();while(!executor.isTerminated()){}System.exit(0);}private static class DeadlockTask1 implements Runnable{public void run(){<span style="color: rgb(153, 0, 0);">synchronized(locker1){</span>System.out.println(" DeadlockTask1 获得锁 locker1 没有死锁!");<span style="color: rgb(204, 0, 0);">synchronized(locker2){</span>System.out.println(" DeadlockTask1 获得锁 locker2 没有死锁!");}}}}private static class DeadlockTask2 implements Runnable{public void run(){<span style="color: rgb(204, 0, 0);">synchronized(locker1){</span>System.out.println(" DeadlockTask2 获得锁 locker2 没有死锁!");<span style="color: rgb(204, 0, 0);">synchronized(locker2){</span>System.out.println(" DeadlockTask2 获得锁 locker1 没有死锁!");}}}}}
0 0
- java多线程 信号量(Semaphore),死锁
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- JAVA多线程--信号量(Semaphore)
- Java多线程:Semaphore信号量
- JAVA多线程--信号量(Semaphore)
- java 多线程-信号量 Semaphore
- Java多线程工具之Semaphore(信号量)
- java多线程的信号量Semaphore
- java多线程控制-信号量Semaphore
- Java多线程之信号量Semaphore
- ORACLE在线切换undo表空间
- 二维线段树
- 你所不知的 CSS ::before 和 ::after 伪元素用法
- Activity
- 高德地图在Fragment运用
- java多线程 信号量(Semaphore),死锁
- 【Linux4.1.12源码分析】协议栈报文接收之IP层处理分析(ip_forward)
- 第九周项目1-猴子选大王(数组版)
- Graphics View Framework之坦克大战(二)
- openWRT的ipk编译方法
- 表分区问题 ORA-02149: Specified partition does not exist
- USACO 提交测试
- android:layout_gravity 和 android:gravity 的区别及LinearLayout何时生效
- 51nod 1005 大数加法