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
复制代码

 

 

 

 

 

posted @   Cynical丶Gary  阅读(338)  评论(0编辑  收藏  举报
编辑推荐:
· 使用 .NET Core 实现一个自定义日志记录器
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
· [杂谈]后台日志该怎么打印
阅读排行:
· 2000 Star,是时候为我的开源项目更新下功能了
· 好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!
· [WPF UI] 为 AvalonDock 制作一套 Fluent UI 主题
· 基于.NET WinForm开发的一款硬件及协议通讯工具
· 工作中这样用MQ,很香!
点击右上角即可分享
微信分享提示