zoukankan      html  css  js  c++  java
  • JAVA中 死锁&线程池

    死锁现象:DeadLock,当多线程访问互斥的网络资源时(共享资源,但是访问顺序相反),由于线程安全问题而加的多层同步,导致程序锁死现象,称为死锁。

    解决死锁的方法:尽量减少加的同步的次数。

    死锁代码示例:

     1 package DemoList;
     2 
     3 public class Demo1 {
     4 
     5     public static void main(String[] args) {
     6         ExtendsThread et1=new ExtendsThread();
     7         ExtendsThread et2=new ExtendsThread();
     8         et1.flag=true;
     9         et2.flag=false;
    10         et1.start();
    11         et2.start();
    12     }
    13 }
    14 class ExtendsThread extends Thread{
    15     static Object obj=new Object();
    16     static Object obj2=new Object();
    17     
    18     boolean flag;
    19     @Override
    20     public void run() {
    21         if(flag) {
    22             synchronized (obj) {
    23                 System.out.println("true obj");    
    24             synchronized (obj2) {
    25                 System.out.println("true obj2");
    26             }
    27         }
    28         }else {
    29             synchronized (obj2) {
    30                 System.out.println("false obj2");
    31             synchronized (obj) {
    32                 System.out.println("false obj");
    33             }
    34             }
    35         }
    36     }
    37 }

     正常的执行结果为:

    但是偶尔会有非正常的执行结果:

    之所以会出现上面的这种情况,是因为计算机的执行速度快,et1在拿到obj1并且拿到obj2之后,et2才开始拿,这时候et1已经将obj1和obj2释放,所以可以四个结果都拿到。

    那么要解决这个问题,可以在第一层锁后边加Thread.sleep()方法,这样确保了et1拿到obj1的时候,et2拿到obj2了,所以不会出现上述情况

    代码示例:

     1 package DemoList;
     2 
     3 public class Demo1 {
     4 
     5     public static void main(String[] args) {
     6         ExtendsThread et1=new ExtendsThread();
     7         ExtendsThread et2=new ExtendsThread();
     8         et1.flag=true;
     9         et2.flag=false;
    10         et1.start();
    11         et2.start();
    12     }
    13 }
    14 class ExtendsThread extends Thread{
    15     static Object obj=new Object();
    16     static Object obj2=new Object();
    17     
    18     boolean flag;
    19     @Override
    20     public void run() {
    21         if(flag) {
    22             synchronized (obj) {
    23                 System.out.println("true obj");    
    24                 try {
    25                     Thread.sleep(100);   //在这里加上Thread.sleep()方法
    26                 } catch (InterruptedException e) {
    27                     // TODO Auto-generated catch block
    28                     e.printStackTrace();
    29                 }
    30             synchronized (obj2) {
    31                 System.out.println("true obj2");
    32             }
    33         }
    34         }else {
    35             synchronized (obj2) {
    36                 System.out.println("false obj2");
    37             synchronized (obj) {
    38                 System.out.println("false obj");
    39             }
    40             }
    41         }
    42     }
    43 }

    线程池:

     存放多个线程的池子:

    线程池产生的原因:降低内存的开销

    使用线程,需要创建线程对象,并且使用完,要销毁线程对象,频繁的创建和销毁线程,会加大内存的开销。

    一个进程,会使用多个线程

    线程池涉及到的类:

    Executors:创建线程池的工具类

    常用方法: newFixedThreadPool(int nThread) 创建固定个数线程的线程池

    ExecutorService 管理线程池的类

    submit(Runnable  task)获取线程的方法

    shoutdown()  关闭

    代码示例:

     1 package DemoList;
     2 
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 
     6 public class Demo9 {
     7 
     8     public static void main(String[] args) {
     9         ExecutorService es=Executors.newFixedThreadPool(3);
    10         es.submit(new ImplementsRunnable2());
    11         es.submit(new ImplementsRunnable2());
    12         es.submit(new ImplementsRunnable2());
    13     }
    14 }
    15 class ImplementsRunnable2 implements Runnable{
    16 
    17     @Override
    18     public void run() {
    19         System.out.println(Thread.currentThread().getName());
    20     }
    21 }

    执行结果:

    线程池和线程组的区别:线程池就是将所有的线程都放在里面,而线程组是将相同的线程放在一起,比如main线程组里都是main方法里的线程,自定义线程组里都是自定义的线程

    如果需要使用的线程数大于线程组里的线程数,那么就会有线程等待,就好像水房里有十个水龙头,但是有二十位同学一起去打水,没抢到水龙头的同学只能等别人打完水了再去打水。

  • 相关阅读:
    Nginx技术研究系列6-配置详解
    IBatis.Net 老技术新研究
    .Net 内存对象分析
    Nginx技术研究系列2-基于Redis实现动态路由
    hexo d 报错‘fatal: could not read Username for 'https://github.com': No error’
    从架构理解价值-我的软件世界观(转载)
    消息队列1:RabbitMQ解析并基于Springboot实战
    PostgreSQL之oracle_fdw安装与使用
    消息队列0:消息队列概述
    Java多线程1:进程和线程的区别
  • 原文地址:https://www.cnblogs.com/ywzbky/p/10725715.html
Copyright © 2011-2022 走看看