zoukankan      html  css  js  c++  java
  • 线程同步、死锁

    1.线程同步(即上锁,同步锁)实现的方式

    1)同步代码块

    synchronized(obj){  //obj称为同步监视器,obj要监视的对象

    }

    同步监视器只能是对象,推荐使用共享资源的对象,可以当前对象 this,也可以是其它的对象

     1 public class Ticket1 implements Runnable{
     2     private int ticket=5;
     3     @Override
     4     public void run() {
     5         for(int i=0;i<100;i++){  //每个窗口排了100个人
     6             synchronized (this) {  //同步代码块
     7                 if(ticket>0){//有票
     8                     try {
     9                         Thread.sleep(300);
    10                     } catch (InterruptedException e) {
    11                         // TODO Auto-generated catch block
    12                         e.printStackTrace();
    13                     }
    14                     System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"张票");
    15                 }
    16             }
    17         }
    18     }
    19 }
    View Code
     1 public class TestTicket1 {
     2     public static void main(String[] args) {
     3         Ticket1 ticket=new Ticket1();
     4         //创建Thread类
     5         Thread t1=new Thread(ticket, "A窗口");
     6         Thread t2=new Thread(ticket,"B窗口");
     7         Thread t3=new Thread(ticket,"C窗口");
     8         //启动线程
     9         t1.start();
    10         t2.start();
    11         t3.start();
    12     }
    13 }
    View Code

    2)同步方法

    同步方法的同步监视器为当前对象this

    public synchronized void 方法名(参数列表){

    }

     1 public class Ticket2 implements Runnable{
     2     private int ticket=5;
     3     @Override
     4     public void run() {
     5         for(int i=0;i<100;i++){  //每个窗口排了100个人
     6              //调用同步方法
     7             this.saleTicket();
     8         }
     9     }
    10     private synchronized void saleTicket(){  //无需指定同步监视器,同步监视器只能是当前对象this
    11         if(ticket>0){//有票
    12             try {
    13                 Thread.sleep(300);
    14             } catch (InterruptedException e) {
    15                 // TODO Auto-generated catch block
    16                 e.printStackTrace();
    17             }
    18             System.out.println(Thread.currentThread().getName()+"正在卖第"+(ticket--)+"张票");
    19         }
    20     }
    21 }
    View Code
     1 public class TestTicket2 {
     2     public static void main(String[] args) {
     3         Ticket2 ticket=new Ticket2();
     4         //创建Thread类
     5         Thread t1=new Thread(ticket, "A窗口");
     6         Thread t2=new Thread(ticket,"B窗口");
     7         Thread t3=new Thread(ticket,"C窗口");
     8         //启动线程
     9         t1.start();
    10         t2.start();
    11         t3.start();
    12     }
    13 }
    View Code

    2.死锁及解决

    产生原因:多线程操作时,互相等待对方的资源

     1 public class DeadLock extends Thread {
     2     private Object money;//
     3     private Object water;//
     4     public boolean flag;//标识持有对象锁
     5     
     6     public DeadLock(Object money, Object water) {
     7         super();
     8         this.money = money;
     9         this.water = water;
    10     }
    11 
    12     @Override
    13     public void run() {
    14         if(flag){//true时,持有“钱”的锁
    15             synchronized (money) {
    16                 System.out.println("有钱,等水");
    17                 try {
    18                     Thread.sleep(300);
    19                 } catch (InterruptedException e) {
    20                     // TODO Auto-generated catch block
    21                     e.printStackTrace();
    22                 }
    23                 synchronized (water) {
    24                     System.out.println("有水,等钱");
    25                 }
    26             }
    27         }else{
    28             synchronized (water) {
    29                 System.out.println("有水,等钱");
    30                 try {
    31                     Thread.sleep(300);
    32                 } catch (InterruptedException e) {
    33                     // TODO Auto-generated catch block
    34                     e.printStackTrace();
    35                 }
    36                 synchronized (money) {
    37                     System.out.println("有钱,等水");
    38                 }
    39             }
    40             
    41         }
    42     }
    43 }
    View Code
     1 public class Test {
     2     public static void main(String[] args) {
     3         //创建共享资源的对象
     4         Object money=new Object();
     5         Object water=new Object();
     6         //创建线程类的对象
     7         DeadLock d1=new DeadLock(money, water);
     8         DeadLock d2=new DeadLock(money, water);
     9         d1.flag=true;
    10         d2.flag=false;
    11         //启动线程
    12         d1.start();
    13         d2.start();
    14     }
    15 }
    View Code

    无法完成一个循环

    如何解决死锁:不要让两个对象同时持有对象锁,采用互斥方式来解决

     把 synchronized嵌套改为同级并列

     1 public class DeadLock2 extends Thread {
     2     private Object money;//
     3     private Object water;//
     4     public boolean flag;//标识持有对象锁
     5     
     6     public DeadLock2(Object money, Object water) {
     7         super();
     8         this.money = money;
     9         this.water = water;
    10     }
    11 
    12     @Override
    13     public void run() {
    14         if(flag){//true时,持有“钱”的锁
    15             synchronized (money) {
    16                 System.out.println("有钱,等水");
    17                 try {
    18                     Thread.sleep(300);
    19                 } catch (InterruptedException e) {
    20                     // TODO Auto-generated catch block
    21                     e.printStackTrace();
    22                 }
    23                 
    24             }
    25             synchronized (water) {
    26                 System.out.println("有水,等钱");
    27             }
    28         }else{
    29             synchronized (water) {
    30                 System.out.println("有水,等钱");
    31                 try {
    32                     Thread.sleep(300);
    33                 } catch (InterruptedException e) {
    34                     // TODO Auto-generated catch block
    35                     e.printStackTrace();
    36                 }
    37                 
    38             }
    39             synchronized (money) {
    40                 System.out.println("有钱,等水");
    41             }
    42             
    43         }
    44     }
    View Code
     1 public class Test2 {
     2     public static void main(String[] args) {
     3         //创建共享资源的对象
     4         Object money=new Object();
     5         Object water=new Object();
     6         //创建线程类的对象
     7         DeadLock2 d1=new DeadLock2(money, water);
     8         DeadLock2 d2=new DeadLock2(money, water);
     9         d1.flag=true;
    10         d2.flag=false;
    11         //启动线程
    12         d1.start();
    13         d2.start();
    14     }
    15 }
    View Code

    死锁的避免

    银行家算法:该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。这样申请者就可很快完成其计算,然后释放它

    占用的资源,从而保证了系统中的所有进程都能完成,所以可避免死锁的发生。(计算资源的大小,计算出来后,永远按照从大到小的方式来获得锁)

  • 相关阅读:
    iOS开发之Xcode8兼容适配iOS 10资料整理笔记
    C#流概述
    C#回调实现的一般过程
    ASP.Net MVC的学习
    RAID基本知识
    Infiniband基本知识
    [转]开源实时视频码流分析软件:VideoEye
    [转]高分一号的落后与特色
    [转]MVC,MVP 和 MVVM 的图示
    图文助你打开MS SQL Serever的ldf和mdf文件
  • 原文地址:https://www.cnblogs.com/bfcs/p/10647799.html
Copyright © 2011-2022 走看看