zoukankan      html  css  js  c++  java
  • Java基础_死锁、线程组、定时器Timer

    一、死锁问题:

      死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

      比如,线程一需要第一把所,此时锁处于空闲状态,给了线程一,线程二需要第二把所,第二把锁也处于空闲状态,给了线程二,这样是没问题的。

      但是,当线程一需要第一把所,线程二需要第二把所后未归还,线程一又需要第二把锁,此时线程一就会一直等待线程二将锁归还,可线程二还是需要线程一的锁,也处于等待的状态,因此,线程一和线程二都保持循环等待,两个线程都无法做完事情归还锁,二者出现死锁情况。。。

      

    package com.Gary1;
    
    public class DeadLock {
    
        public static Object lock1 = new Object();
        public static Object lock2 = new Object();
        
        
        public static void main(String[] args) {
            
            new Thread(new Thread1()).start();
            new Thread(new Thread2()).start();
            
        }
        
    }
    
    class Thread1 implements Runnable{
    
        @Override
        public void run() {
            synchronized(DeadLock.lock1) {
                System.out.println("取得第一把锁之后要做的事情");
                try {
                    //耗时100毫秒,继续做一些事情
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(DeadLock.lock2) {
                    System.out.println("Thread1同时取得两把锁之后要做的事情");
                }
            }
            
        }
    }
    
    class Thread2 implements Runnable{
    
        @Override
        public void run() {
            synchronized(DeadLock.lock2) {
                System.out.println("取得第二把锁之后要做的事情");
                try {
                    //耗时100毫秒,继续做一些事情
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(DeadLock.lock1) {
                    System.out.println("Thread2同时取得两把锁之后要做的事情");
                }
            }
            
            
        }
    }
    DeadLock.java

      避免这种情况出现最好的方法:解决上锁的顺序

      两边线程上锁顺序lock1->lock2

    package com.Gary1;
    
    public class DeadLock {
    
        public static Object lock1 = new Object();
        public static Object lock2 = new Object();
        
        
        public static void main(String[] args) {
            
            new Thread(new Thread1()).start();
            new Thread(new Thread2()).start();
            
        }
        
    }
    
    class Thread1 implements Runnable{
    
        @Override
        public void run() {
            synchronized(DeadLock.lock1) {
                System.out.println("取得第一把锁之后要做的事情");
                try {
                    //耗时100毫秒,继续做一些事情
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(DeadLock.lock2) {
                    System.out.println("Thread1同时取得两把锁之后要做的事情");
                }
            }
            
        }
    }
    
    class Thread2 implements Runnable{
    
        @Override
        public void run() {
            synchronized(DeadLock.lock1) {
                System.out.println("取得第二把锁之后要做的事情");
                try {
                    //耗时100毫秒,继续做一些事情
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized(DeadLock.lock2) {
                    System.out.println("Thread2同时取得两把锁之后要做的事情");
                }
            }
            
            
        }
    }
    DeadLock.java

    二、线程组ThreadGroup 默认处于同一个组里面

        使用线程组可以统一设置这个组内线程的一些东西。比如设置优先级,设置是否是守护线程

        ThreadGroup tg = new ThreadGroup("我们的线程组");
            
        Thread t1 = new Thread(tg,r);
        Thread t2 = new Thread(tg,r);
            
        //批量管理
        tg.interrupt();//中断里边所有线程
        tg.setDaemon(true);//设置守护线程
        tg.setMaxPriority(9);//设置线程组最大优先级

      

    package com.Gary1;
    
    public class ThreadGroupDemo {
    
        public static void main(String[] args) {
            MyRunnable r = new MyRunnable();
            
            ThreadGroup tg = new ThreadGroup("我们的线程组");
            
            Thread t1 = new Thread(tg,r);
            Thread t2 = new Thread(tg,r);
            
            //批量管理
            tg.interrupt();//中断里边所有线程
            tg.setDaemon(true);//设置守护线程
            tg.setMaxPriority(9);//设置线程组最大优先级
            
            //ThreadGroup tg = t1.getThreadGroup();
            //输出线程名字
            //System.out.println(tg.getName());
            //输出线程组名字
            //System.out.println(t2.getThreadGroup().getName());
            
            t1.start();
            t2.start();
            
        }
        
    }
    ThreadGroupDemo.java
    package com.Gary1;
    
    public class MyRunnable implements Runnable{
    
        private String data = "";
        
        @Override
        public void run() {
            for(int i=0;i<100;i++) {
                Thread t = Thread.currentThread();
                System.out.println(t.getName()+":"+i);
            }
            
        }
    
    }
    MyRunnable.java

    三、定时器Timer

      作用:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。 

      使用类:Timer和TimerTask

      常用方法:

        timer.schedule(TimerTask task, long delay)   

        timer.schedule(TimerTask task, long delay, long period) 

        timer.schedule(TimerTask task, Date time) 

        timer.cancel();

    public static void main(String[] args) {
            //Timer TimerTask
            Timer t = new Timer();
            
            //定义一个定时器任务,2000毫秒开始执行
            //t.schedule(new MyTimerTask(), 2000);
            //定义一个定时器任务,2000毫秒开始执行,每个3000毫秒执行一次
            //t.schedule(new MyTimerTask(), 2000,3000);
            //在哪个时间开始执行这个任务
            //t.schedule(new MyTimerTask(), time);
            //终止定时器任务执行
            //timer.cancel();
        }
    package com.Gary1;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class TimerDemo {
        public static void main(String[] args) {
            //Timer TimerTask
            Timer t = new Timer();
            
            //定义一个定时器任务,2000毫秒开始执行
            //t.schedule(new MyTimerTask(), 2000);
            //定义一个定时器任务,2000毫秒开始执行,每个3000毫秒执行一次
            //t.schedule(new MyTimerTask(), 2000,3000);
            //在哪个时间开始执行这个任务
            //t.schedule(new MyTimerTask(), time);
            //终止定时器任务执行
            //timer.cancel();
        }
    
    }
    
    class MyTimerTask extends TimerTask{
    
        @Override
        public void run() {
            System.out.println("定时器任务");
            
        }
        
    }
    TimerDemo.java
  • 相关阅读:
    CAST()类型转换函数
    CLR LOH的危险
    保持积极的态度,态度决定一切!
    as 操作符和强行转换的区别
    查内存覆盖从以前的帖子里总结的
    CLR中的范型为什么不支持很多操作符?
    如何做一个好的Team Leader?
    Dispose Pattern总结
    慎用Reflection
    CLR Enum类型内幕
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/11946543.html
Copyright © 2011-2022 走看看