java-synchronized 的示例


import java.util.concurrent.TimeUnit;

/**
 * 1、标准访问,先打印邮件还是短信?
 * 邮件、短信 ; synchronized锁的是当前实列对象,如果一个对象里有多个synchronized方法,某一时刻内,
 * 只要一个线程去调用其中的一个synchronized方法,其他的线程只能等待;某一时刻内 只能有唯一一个线程去访问这些synchronized方法;
 * 2、邮件方法暂停4秒钟,先打印邮件还是短信?
 * 邮件、短信;
 * 3、新增一个普通方法hello(),先打印邮件还是hello?  先 hello 后邮件
 * 普通方法没有锁,也无争抢,所以先执行hello 在次执行 发送邮件
 *
 * 4、两部手机,先打印邮件还是短信?
 * 可能性两种:因为是两个实例(对象锁),加锁以后 各锁各的,无竞争 互不相干
 *
 * 5、两个静态同步方法,同一部手机,先打印邮件还是短信?
 * 邮件、短信   static锁定的是类
 *
 * 6、两个静态同步方法,2部手机,先打印邮件还是短信?
 * 邮件、短信  static锁定的是类
 *
 * 7、1个普通方法,1个静态同步方法,1部手机,先打印邮件还是短信?
 * 短信、邮件  普通方法是锁的实例对象this 而 静态方法锁的是一个类模板,两个不同的锁
 * 静态同步方法、邮件
 *
 * 8、1个普通方法,1个静态同步方法,2部手机,先打印邮件还是短信?
 *  短信、邮件  普通方法是锁的实例对象this 而 静态方法锁的是一个类模板,两个不同的锁
 * @author L
 *
 */
class Phone{
    
    public      void sendEmail() {
        
        try {
             TimeUnit.SECONDS.sleep(4);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("----senEmail");
    }
    
    public static  synchronized void sendSMS() {
        
        System.out.println("----sendSMS");
    }
    
    public void hello() {
        System.out.println("------hello");
    }
    
}

public class MoneyThreadDemo {
    
    public static void main(String[] args) {
        
        Phone phone=new Phone();
        
        Phone phone2=new Phone();
        
        new Thread(()->{
            
            phone.sendEmail();
            
        },"A") .start();
        
        try {
            // Thread.sleep(100);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    
        new Thread(()->{
            phone2.sendSMS();
        //    phone.hello();
        },"B") .start();
        
        new Thread(()->{
             phone.hello();
        //    phone.hello();
        },"C") .start();
        
        
    }
}

/**所有的非静态同步方法用的都是一把锁--实例对象本身
 * synchronized 实现同步的基础:java中的每一个对象都可以作为锁;
 * 具体表现为以下3种形式;
 * 对于普通方法,锁是当前实例对象
 * 对于静态方法,锁是当前class对象
 * 对于同步方法块,锁是synchronized括号里配置的对象
 * 当一个线程视图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁
 *
 * 所有的静态同步方法用的也是同一把锁---》类对象本身,这两把锁是两个不同的对象,所以静态
 * 同步方法与非静态同步方法之间时不会有意态条件的。
 * 但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放后才能获取资源,
 * 而不管是同一个实例对象的静态同步方法之间。
 * 还是不同的实例对象的静态同步方法之间,只要它们一个类的实例对象;
 * @author L
 *
 */

原文地址:https://www.cnblogs.com/hellohero55/p/12247687.html