zoukankan      html  css  js  c++  java
  • 线程同步(线程安全处理Synchronized)与死锁

    一  线程同步

    java中提供了线程同步机制,它能够解决上述的线程安全问题。

             线程同步的方式有两种:

    方式1:同步代码块

      方式2:同步方法

    1 同步代码块

    同步代码块: 在代码块声明上 加上synchronized

    synchronized (锁对象) {
        可能会产生线程安全问题的代码
    }

    同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

    使用同步代码块,对电影院卖票案例中Ticket类进行如下代码修改

    package com.oracle.demo01;
    
    public class Myticket implements Runnable {
        private int ticket=100;
        private Object obj=new Object();
        public void run() {
            while(true){
                synchronized (obj) {
                if(ticket>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"出售第"+ticket--+"张票");
                }
                }
            }
        }
        
    }

    运行结果为:

    这样就解决了线程安全的问题

    2  同步方法

      同步方法:在方法声明上加上synchronized

    public synchronized void method(){
           可能会产生线程安全问题的代码
    }

    同步方法中的锁对象是 this

    使用同步方法,对电影院卖票案例中Ticket类进行如下代码修改:

    package com.oracle.demo01;
    
    public class Myticket2 implements Runnable {
        private int ticket=100;
        //同步方法是否有锁对象?有   this
        //静态同步方法有锁对象?有,MyTicket2.class
        //同步怎么保证安全性?没有锁的线程不能执行只能等
        //加了同步,线程进同步判断锁的时候,比如,获取锁,释放锁,导致运行速度慢
        //StringBuilder比StringBuffer快的原因
        //StringBuffer里面的所有方法都加了同步关键字,所以慢,但安全
        //StringBuilder是没有的,所以快,但不安全
        public synchronized void sale(){
            //可能会产生线程安全问题的代码
            if(ticket>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"出售第"+ticket--+"张票");
            }
        }
        public void run() {
            while(true){
                sale();
            }
        }
        
    }

    二  死锁

    同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步。这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁。这种情况能避免就避免掉。

    package com.oracle.demo02;
    
    public class DeadLock implements Runnable {
        private int i=0;
        public void run() {
            while(true){
                if(i%2==0){
                    //先进A同步,再进B同步
                    synchronized (LockA.locka) {
                        System.out.println("if...locka");
                        synchronized (LockB.lockb) {
                            System.out.println("if...lockb");
                        }
                    }
                }else{
                    //先进B同步,再进A同步
                    synchronized (LockB.lockb) {
                        System.out.println("else...lockb");
                        synchronized (LockA.locka) {
                            System.out.println("else...locka");
                        }
                    }
                }
                i++;
            }
        }
    }

    程序无线等待

  • 相关阅读:
    某个牛人做WINDOWS系统文件详解
    常用ASP脚本程序集锦
    LINUX基础:文件安全与权限
    proftpd+mysql+quota
    apache2.0.49tomcat5.0.19jk2建立virtualHost
    URL Redirection(转) Anny
    顶级域名后缀列表(转) Anny
    \u4E00\u9FA5意义 Anny
    How to POST Form Data Using Ruby(转) Anny
    How to get rid of 'Enter password to unlock your login keyring' in Ubuntu(转) Anny
  • 原文地址:https://www.cnblogs.com/zzq123/p/10248621.html
Copyright © 2011-2022 走看看