zoukankan      html  css  js  c++  java
  • java多线程之死锁

    产生死锁的条件:

    1.有至少一个资源不能共享
    2.至少有一个任务必须持有一个资源并且等待获取另一个被别的任务持有的资源
    3.资源不能任务抢占
    4.必须有循环等待

    只要打破其中一个条件就不会产生死锁,通常是打破第4个条件

    package DeadLock;
    
    public class Chopstick {
        private boolean taken = false;
    
        public synchronized void take() throws InterruptedException {
            while (taken) {
                wait();
            }
            taken = true;
        }
    
        public synchronized void drop() {
            taken = false;
            notifyAll();
        }
    }
    package DeadLock;
    
    import java.util.Random;
    import java.util.concurrent.TimeUnit;
    
    public class Philosopher implements Runnable {
    
        private Chopstick left;
        private Chopstick right;
        private final int id;
        private final int ponderFactor;
        private Random rand = new Random(47);
    
        private void pause() throws InterruptedException {
            if (ponderFactor == 0)
                return;
            
            //赞同随机毫秒数
            TimeUnit.MILLISECONDS.sleep(rand.nextInt(ponderFactor * 250));
        }
    
        public Philosopher(Chopstick left, Chopstick right, int ident, int ponder) {
            this.left = left;
            this.right = right;
            id = ident;
            ponderFactor = ponder;
        }
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    System.out.println(this + " " + "thinking");
                    pause();
                    // Philosopher becomes hungry
                    System.out.println(this + " " + " grabbing right");
                    right.take();
                    System.out.println(this + " " + "grabbing left");
                    left.take();
                    System.out.println(this + " " + "eating");
                    pause();
                    right.drop();
                    left.drop();
                }
            } catch (InterruptedException e) {
                System.out.println(this + " " + "exiting via interrupt");
            }
        }
    
        public String toString() {
            return "Philosopher " + id;
        }
    
    }

    造成死锁

    package DeadLock;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    public class DeadlockingDiningPhilosophers {
        public static void main(String[] args) throws Exception {
            int ponder = 5;
            if (args.length > 0)
                ponder = Integer.parseInt(args[0]);
    
            int size = 5;
            if (args.length > 1)
                size = Integer.parseInt(args[1]);
    
            ExecutorService exec = Executors.newCachedThreadPool();
            Chopstick[] sticks = new Chopstick[size];
            for (int i = 0; i < size; i++) {
                exec.execute(new Philosopher(sticks[i], sticks[(i + 1) % size], i,
                        ponder));
            }
            if (args.length == 3 && args[2].equals("timeout"))
                TimeUnit.SECONDS.sleep(5);
            else {
                System.out.println("Press'Enter' to quit");
                System.in.read();
            }
            exec.shutdownNow();
        }
    }

    避免死锁

    package DeadLock;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    import javax.print.attribute.Size2DSyntax;
    
    public class FixedDiningPhilosophers {
        public static void main(String[] args) throws Exception{
            int ponder=5;
            if(args.length>0)
                ponder=Integer.parseInt(args[0]);
            
            int size=5;
            if(args.length>1)
                size=Integer.parseInt(args[1]);
            ExecutorService exec=Executors.newCachedThreadPool();
            Chopstick[] sticks=new Chopstick[size];
            for (int i = 0; i < size; i++) {
                sticks[i]=new Chopstick();
            }
            for (int i = 0; i < size; i++) {
                if(i<(size-1))
                    exec.execute(new Philosopher(sticks[i],sticks[i+1], i, ponder));
                else
                    exec.execute(new Philosopher(sticks[0], sticks[i], i, ponder));
            }
            if(args.length==3&&args[2].equals("timeout"))
                TimeUnit.SECONDS.sleep(5);
            else{
                System.out.println("Press 'Enter' to quit");
                System.in.read();
            }
            exec.shutdownNow();
        }
    }
  • 相关阅读:
    kail
    scp命令
    搭建LNMP
    PHP7.3.2安装
    nginx的安装
    CentOS7部署NFS
    Linux使用mailx通过外部smtp发邮件
    kickstart自动化安装
    centos7下单用户模式,救援模式的应用以及虚拟机下的克隆
    putty和xsheel远程连接centos7
  • 原文地址:https://www.cnblogs.com/zhuawang/p/3782814.html
Copyright © 2011-2022 走看看