• java 多线程(1) 多线程死锁与同步超时的实现


      死锁是两个甚至多个线程被永久阻塞时的一种运行局面,这种局面的生成伴随着至少两个线程和两个或者多个资源。

      死锁例子:

    public class ThreadDeadlock {
     
        public static void main(String[] args) throws InterruptedException {
            Object obj1 = new Object();
            Object obj2 = new Object();
            Object obj3 = new Object();
     
            Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
            Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
            Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
     
            t1.start();
            Thread.sleep(5000);
            t2.start();
            Thread.sleep(5000);
            t3.start();
     
        }
     
    }
     
    class SyncThread implements Runnable{
        private Object obj1;
        private Object obj2;
     
        public SyncThread(Object o1, Object o2){
            this.obj1=o1;
            this.obj2=o2;
        }
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            System.out.println(name + " acquiring lock on "+obj1);
            synchronized (obj1) {
             System.out.println(name + " acquired lock on "+obj1);
             work();
             System.out.println(name + " acquiring lock on "+obj2);
             synchronized (obj2) {
                System.out.println(name + " acquired lock on "+obj2);
                work();
            }
             System.out.println(name + " released lock on "+obj2);
            }
            System.out.println(name + " released lock on "+obj1);
            System.out.println(name + " finished execution.");
        }
        private void work() {
            try {
                Thread.sleep(30000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    避免死锁

    有很多方针可供我们使用来避免死锁的局面。

    • 避免嵌套封锁:这是死锁最主要的原因的,如果你已经有一个资源了就要避免封锁另一个资源。如果你运行时只有一个对象封锁,那是几乎不可能出现一个死锁局面的。例如,这里是另一个运行中没有嵌套封锁的run()方法,而且程序运行没有死锁局面,运行得很成功。
    • 只对有请求的进行封锁:你应当只想你要运行的资源获取封锁,比如在上述程序中我在封锁的完全的对象资源。但是如果我们只对它所属领域中的一个感兴趣,那我们应当封锁住那个特殊的领域而并非完全的对象。
    • 避免无限期的等待:如果两个线程正在等待对象结束,无限期的使用线程加入,如果你的线程必须要等待另一个线程的结束,若是等待进程的结束加入最好准备最长时间。

      使用java.util.concurrent包里面的类设置超时。

      

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    
    public strictfp class Main{
        public static void main(String[] args) throws InterruptedException{
            ExecutorService executor = Executors.newSingleThreadExecutor();  
            FutureTask<String> futureTask =  
                   new FutureTask<String>(new Callable<String>() {
                       public String call() {  
                           //真正的任务在这里执行,这里的返回值类型为String,可以为任意类型  
                           try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            System.out.println("interruptered");
                        }
                           return "haha";
                       }
                }); 
            executor.execute(futureTask);  
            //在这里可以做别的任何事情  
            String result=null;
            try {  
                result = futureTask.get(1000, TimeUnit.MILLISECONDS); //取得结果,同时设置超时执行时间为5秒。同样可以用future.get(),不设置执行超时时间取得结果  
            } catch (InterruptedException e) {  
                futureTask.cancel(true);  
            } catch (ExecutionException e) {  
                futureTask.cancel(true);  
            } catch (TimeoutException e) {  
                futureTask.cancel(true);  
            } finally {  
                executor.shutdown();  
            }
            System.out.println(result);
        }
    }
  • 相关阅读:
    ubuntu16.04下vim安装失败
    Sql Server函数全解(三)数据类型转换函数和文本图像函数
    Sql Server函数全解(二)数学函数
    Sql server 2008 中varbinary查询
    处理乱码问题
    快速排序
    《Java编程思想》笔记 第二章 一切都是对象
    1021: 组合数末尾的零
    11462
    The Bus Driver Problem
  • 原文地址:https://www.cnblogs.com/maydow/p/4899110.html
Copyright © 2020-2023  润新知