java 解决死锁(程序模拟)

为了解决程序因占用资源,出现资源争抢,而出现的程序进入等待的状态(死锁)。

解决这种问题:

我们可以给资源加上“锁”,在每次调用前进行判断当前锁的状态,再进行执行。

下面是模拟程序:

package com.yxy.thread;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Random;

/**
 * @author windows
 * 安全锁例子
 */
public class Safelock {
	
    /**
     * @author windows
     * 朋友实体类
     */
    static class Friend {
    	//朋友类,锁(重入锁)
        private final String name;
        private final Lock lock = new ReentrantLock();
        //朋友构造方法
        public Friend(String name) {
            this.name = name;
        }
        //获取名字
        public String getName() {
            return this.name;
        }
        //在鞠躬前的判断
        public boolean impendingBow(Friend bower) {
        	//当前我的状态锁,与朋友的状态锁
            Boolean myLock = false;
            Boolean yourLock = false;
            try {
            	//记录当前类的锁,和鞠躬的朋友的锁的状态
                myLock = lock.tryLock();
                yourLock = bower.lock.tryLock();
            } finally {
            	//如果当前类的锁,与鞠躬朋友的类的状态,其中有一个为false时
                if (! (myLock && yourLock)) {
                	//判断是那个状态为true的,对这个锁进行解锁。
                    if (myLock) {
                        lock.unlock();
                    }
                    if (yourLock) {
                        bower.lock.unlock();
                    }
                }
            }
            //返回结果
            return myLock && yourLock;
        }
            
        /**
         * @param bower
         * 向朋友鞠躬的方法
         */
        public void bow(Friend bower) {
        	//判断是否有锁
            if (impendingBow(bower)) {
            	//朋友鞠躬时,我没有鞠躬。打印出信息,并回敬。
                try {
                    System.out.format("%s: %s has"
                        + " bowed to me!%n", 
                        this.name, bower.getName());
                    bower.bowBack(this);
                } finally {
                    lock.unlock();
                    bower.lock.unlock();
                }
            } else {
            	//朋友鞠躬的同时我也鞠躬。打印出信息。
                System.out.format("%s: %s started"
                    + " to bow to me, but saw that"
                    + " I was already bowing to"
                    + " him.%n",
                    this.name, bower.getName());
            }
        }

        /**
         * @param bower
         * 回敬鞠躬的方法。
         */
        public void bowBack(Friend bower) {
            System.out.format("%s: %s has" +
                " bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    /**
     * @author windows
     * 循环鞠躬的线程
     */
    static class BowLoop implements Runnable {
    	//相互鞠躬的两个人
        private Friend bower;
        private Friend bowee;

        //构造方法
        public BowLoop(Friend bower, Friend bowee) {
            this.bower = bower;
            this.bowee = bowee;
        }
    
        //线程的执行方法
        public void run() {
            Random random = new Random();
            for (;;) {//无限循环。
                try {
                	//进程中断
                    Thread.sleep(random.nextInt(5));
                } catch (InterruptedException e) {}
                //bowee向bower鞠躬
                bowee.bow(bower);
            }
        }
    }
            
    //测试
    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new BowLoop(alphonse, gaston)).start();
        new Thread(new BowLoop(gaston, alphonse)).start();
    }
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用以下伪代码实现死锁避免算法: ```java // 定义资源类 class Resource { // 资源的数量 private int count; // 获取资源 public synchronized void acquire() { while (count == 0) { try { // 资源数量为0时,等待其他进程释放资源 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 资源数量减1 count--; } // 释放资源 public synchronized void release() { // 资源数量加1 count++; // 通知其他等待资源的进程 notifyAll(); } } // 定义进程类 class Process { // 进程需要的资源数量 private int need; // 进程已经获取的资源数量 private int acquired; // 进程请求资源时的方法 public synchronized void request(Resource resource) { while (need > resource.getCount()) { try { // 资源数量不足时,等待其他进程释放资源 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 获取资源 resource.acquire(); // 更新进程已经获取的资源数量 acquired++; } // 释放资源时的方法 public synchronized void release(Resource resource) { // 释放资源 resource.release(); // 更新进程已经获取的资源数量 acquired--; // 通知其他等待资源的进程 notifyAll(); } } // 定义主程序 public class Main { public static void main(String[] args) { // 创建一个资源对象 Resource resource = new Resource(); // 创建多个进程对象 Process process1 = new Process(); Process process2 = new Process(); Process process3 = new Process(); // 运行多个进程,每个进程请求和释放资源 new Thread(() -> { process1.request(resource); // ... process1.release(resource); }).start(); new Thread(() -> { process2.request(resource); // ... process2.release(resource); }).start(); new Thread(() -> { process3.request(resource); // ... process3.release(resource); }).start(); } } ``` 在上述代码中,Resource类表示系统中的资源,Process类表示系统中的进程,Main类是主程序。在Process类中,request()方法表示进程请求资源的过程,release()方法表示进程释放资源的过程。在Resource类中,acquire()方法表示资源的获取过程,release()方法表示资源的释放过程。在Main类中,创建Resource和Process对象,并开启多个线程模拟多个进程同时请求和释放资源的过程。通过使用synchronized关键字和wait()、notifyAll()方法来实现多线程之间的同步和通信,从而避免死锁的发生。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值