zoukankan      html  css  js  c++  java
  • 理解java中【同步】和【死锁】

    一.理解同步

    要想解决资源共享的同步操作问题,可以使用两种方法:

    1. 使用同步代码块

    之前学习过程中,代码块分为四种:

    l         普通代码块:是直接定义在方法之中的;

    l         构造块:是直接定义在类中的,优先于构造方法执行,会重复调用;

    l         静态块:是使用static关键字声明的,优先于构造块执行,并且只执行一次;

    l         同步代码块:是使用synchronized关键字声明的代码块,称为同步代码块

    同步的时候必须指明同步的对象,一般情况下会将当前对象作为同步的对象,使用this关键字表示。 注意,同步会使程序运行变慢!

    代码如下:

    package cn.test.java.mutilthread;

     

    class SyncThread2 implements Runnable{

        private int ticket = 10;

        public void run(){

           for(int i = 0;i>10;i++){

               synchronized (this) {

                  if(this.ticket>0){

                      try {

                         Thread.sleep(1000);

                      } catch (InterruptedException e) {

                         // TODO Auto-generated catch block

                         e.printStackTrace();

                      }

                      System.out.println(Thread.currentThread().getName()+"剩下票数:"+ticket--);       

                  }            

               }

           }

        }  

    }

     

    public class SyncThreadDemo2 {

     

        public static void main(String[] args) {

           SyncThread2 t = new SyncThread2();

           Thread t1 = new Thread(t);

           Thread t2 = new Thread(t);

           Thread t3 = new Thread(t);

          

           t1.start();

           t2.start();

           t3.start();

     

        }

     

    }

    1. 使用同步方法

    package cn.test.java.mutilthread;

     

    class SyncThread3 implements Runnable{

        private int ticket = 10;

        public void run(){

           for(int i = 0;i>10;i++){

           this.sale();// 调用同步方法

           }

        }  

        public synchronized void sale(){ //声明同步方法

           if(this.ticket>0){

               try {

                  Thread.sleep(1000);

               } catch (InterruptedException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

               }

               System.out.println(Thread.currentThread().getName()+"剩下票数:"+ticket--);      

           }         

        }

    }

     

    public class SyncThreadDemo3 {

     

        public static void main(String[] args) {

           SyncThread3 t = new SyncThread3();

           Thread t1 = new Thread(t);

           Thread t2 = new Thread(t);

           Thread t3 = new Thread(t);

          

           t1.start();

           t2.start();

           t3.start();

     

        }

    }

    二.理解死锁

    死锁的出现是因为多个线程占用资源之后,没有进行释放,导致其他线程一直处于等待状态,在我们在代码中,出现死锁的原因有很多,极大多数是因为我们代码中编成的同步代码过多导致死锁的,

    注意:使用synchronized同步代码中嵌入synchronized代码,非常容易导致死锁的出现。

    代码如下:

    class Zhangsan{     // 定义张三类

           public void say(){

                  System.out.println("张三对李四说:“你给我画,我就把书给你。”") ;

           }

           public void get(){

                  System.out.println("张三得到画了。") ;

           }

    };

    class Lisi{      // 定义李四类

           public void say(){

                  System.out.println("李四对张三说:“你给我书,我就把画给你”") ;

           }

           public void get(){

                  System.out.println("李四得到书了。") ;

           }

    };

    public class ThreadDeadLock implements Runnable{

           private static Zhangsan zs = new Zhangsan() ;            // 实例化static型对象

           private static Lisi ls = new Lisi() ;        // 实例化static型对象

           private boolean flag = false ;  // 声明标志位,判断那个先说话

           public void run(){   // 覆写run()方法

                  if(flag){

                         synchronized(zs){  // 同步张三

                                zs.say() ;

                                try{

                                       Thread.sleep(500) ;

                                }catch(InterruptedException e){

                                       e.printStackTrace() ;

                                }

                                synchronized(ls){

                                       zs.get() ;

                                }

                         }

                  }else{

                         synchronized(ls){

                                ls.say() ;

                                try{

                                       Thread.sleep(500) ;

                                }catch(InterruptedException e){

                                       e.printStackTrace() ;

                                }

                                synchronized(zs){

                                       ls.get() ;

                                }

                         }

                  }

           }

           public static void main(String args[]){

                  ThreadDeadLock t1 = new ThreadDeadLock() ;         // 控制张三

                  ThreadDeadLock t2 = new ThreadDeadLock() ;         // 控制李四

                  t1.flag = true ;

                  t2.flag = false ;

                  Thread thA = new Thread(t1) ;

                  Thread thB = new Thread(t2) ;

                  thA.start() ;

                  thB.start() ;

           }

    };

    三.总结

    1.多个线程在访问同一资源的时候需要进行同步操作。

    2.同步使用synchronized关键字完成,分为同步代码块及同步方法。

    3.过多的同步有可能造成死锁的产生,死锁是在程序运行时的一种状态,了解就行了。

    4.想停止线程,在代码中设置标志位flag,利用标志位来控制线程在生命周期。

  • 相关阅读:
    java基础练习 4
    java基础练习 5
    java基础练习 3
    java基础练习 2
    二级联动菜单动态刷新下拉列表的一种实现方法
    疯狂Java讲义笔记(二)
    Windows10 Internet Explorer已停止工作的解决方法
    Git笔记
    Spring Boot笔记
    maven笔记
  • 原文地址:https://www.cnblogs.com/luihengk/p/3593002.html
Copyright © 2011-2022 走看看