黑马程序员_日记14_Java多线程(四)

 ——- android培训java培训、期待与您交流! ———-

同步函数的锁是this

同步函数用的是哪一个锁呢?

通过下列程序进行验证。

使用两个线程来买票。
一个线程在同步代码块中。
一个线程在同步函数中。
都在执行买票动作。

class Ticket implements Runnable
{
    private  int tick = 100;
    Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(obj)
                {
                    if(tick>0)
                    {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                    }
                }
            }
        }
        else
            while(true)
                show();
    }
    public synchronized void show()//this
    {
        if(tick>0)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
        }
    }
}


class  ThisLockDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        t.flag = false;
        t2.start();

    }
}

运行结果:
Thread-1….show…. : 100
Thread-1….show…. : 99
Thread-0….show…. : 98
Thread-0….show…. : 97
Thread-0….show…. : 96
Thread-0….show…. : 95
Thread-0….show…. : 94
Thread-0….show…. : 93
Thread-0….show…. : 92
Thread-0….show…. : 91
Thread-0….show…. : 90
Thread-0….show…. : 89
Thread-0….show…. : 88
Thread-0….show…. : 87
Thread-0….show…. : 86
Thread-0….show…. : 85
Thread-0….show…. : 84
Thread-0….show…. : 83
Thread-0….show…. : 82
Thread-0….show…. : 81
Thread-0….show…. : 80
Thread-0….show…. : 79
Thread-0….show…. : 78
Thread-1….show…. : 77
Thread-1….show…. : 76
Thread-1….show…. : 75
Thread-1….show…. : 74
Thread-1….show…. : 73
Thread-1….show…. : 72
Thread-1….show…. : 71
Thread-1….show…. : 70
Thread-1….show…. : 69
Thread-1….show…. : 68
Thread-1….show…. : 67
Thread-1….show…. : 66
Thread-1….show…. : 65
Thread-1….show…. : 64
Thread-1….show…. : 63
Thread-1….show…. : 62
Thread-1….show…. : 61
Thread-1….show…. : 60
Thread-1….show…. : 59
Thread-1….show…. : 58
Thread-1….show…. : 57
Thread-1….show…. : 56
Thread-1….show…. : 55
Thread-1….show…. : 54
Thread-1….show…. : 53
Thread-1….show…. : 52
Thread-1….show…. : 51
Thread-1….show…. : 50
Thread-1….show…. : 49
Thread-1….show…. : 48
Thread-1….show…. : 47
Thread-1….show…. : 46
Thread-1….show…. : 45
Thread-1….show…. : 44
Thread-1….show…. : 43
Thread-1….show…. : 42
Thread-1….show…. : 41
Thread-1….show…. : 40
Thread-1….show…. : 39
Thread-1….show…. : 38
Thread-1….show…. : 37
Thread-1….show…. : 36
Thread-1….show…. : 35
Thread-1….show…. : 34
Thread-1….show…. : 33
Thread-1….show…. : 32
Thread-1….show…. : 31
Thread-1….show…. : 30
Thread-1….show…. : 29
Thread-1….show…. : 28
Thread-1….show…. : 27
Thread-1….show…. : 26
Thread-1….show…. : 25
Thread-1….show…. : 24
Thread-1….show…. : 23
Thread-1….show…. : 22
Thread-1….show…. : 21
Thread-1….show…. : 20
Thread-1….show…. : 19
Thread-1….show…. : 18
Thread-1….show…. : 17
Thread-1….show…. : 16
Thread-1….show…. : 15
Thread-1….show…. : 14
Thread-1….show…. : 13
Thread-1….show…. : 12
Thread-1….show…. : 11
Thread-1….show…. : 10
Thread-1….show…. : 9
Thread-0….show…. : 8
Thread-0….show…. : 7
Thread-0….show…. : 6
Thread-0….show…. : 5
Thread-0….show…. : 4
Thread-0….show…. : 3
Thread-0….show…. : 2
Thread-0….show…. : 1

结果显示:两个线程都只是调用了show方法,为什么呢??
因为start方法仅仅是把线程创建,线程还没有运行。
当主线程执行完毕的时候,flag=false;两个线程只会调用show方法。

下面让主线程睡10毫秒,测试一下

class Ticket implements Runnable
{
    private  int tick = 100;
    Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(obj)
                {
                    if(tick>0)
                    {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                    }
                }
            }
        }
        else
            while(true)
                show();
    }
    public synchronized void show()//this
    {
        if(tick>0)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
        }
    }
}


class  ThisLockDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();

    }
}

运行结果是:
Thread-0….code : 100
Thread-1….show…. : 99
Thread-0….code : 98
Thread-1….show…. : 97
Thread-0….code : 96
Thread-1….show…. : 95
Thread-0….code : 94
Thread-1….show…. : 93
Thread-0….code : 92
Thread-1….show…. : 91
Thread-0….code : 90
Thread-1….show…. : 89
Thread-0….code : 88
Thread-1….show…. : 87
Thread-0….code : 86
Thread-1….show…. : 85
Thread-0….code : 84
Thread-1….show…. : 83
Thread-0….code : 82
Thread-1….show…. : 81
Thread-0….code : 80
Thread-1….show…. : 79
Thread-0….code : 78
Thread-1….show…. : 77
Thread-0….code : 76
Thread-1….show…. : 75
Thread-0….code : 74
Thread-1….show…. : 73
Thread-0….code : 72
Thread-1….show…. : 71
Thread-0….code : 70
Thread-1….show…. : 69
Thread-0….code : 68
Thread-1….show…. : 67
Thread-0….code : 66
Thread-1….show…. : 65
Thread-0….code : 64
Thread-1….show…. : 63
Thread-0….code : 62
Thread-1….show…. : 61
Thread-0….code : 60
Thread-1….show…. : 59
Thread-0….code : 58
Thread-1….show…. : 57
Thread-0….code : 56
Thread-1….show…. : 55
Thread-0….code : 54
Thread-1….show…. : 53
Thread-0….code : 52
Thread-1….show…. : 51
Thread-0….code : 50
Thread-1….show…. : 49
Thread-0….code : 48
Thread-1….show…. : 47
Thread-0….code : 46
Thread-1….show…. : 45
Thread-0….code : 44
Thread-1….show…. : 43
Thread-0….code : 42
Thread-1….show…. : 41
Thread-0….code : 40
Thread-1….show…. : 39
Thread-0….code : 38
Thread-1….show…. : 37
Thread-0….code : 36
Thread-1….show…. : 35
Thread-0….code : 34
Thread-1….show…. : 33
Thread-0….code : 32
Thread-1….show…. : 31
Thread-0….code : 30
Thread-1….show…. : 29
Thread-0….code : 28
Thread-1….show…. : 27
Thread-0….code : 26
Thread-1….show…. : 25
Thread-0….code : 24
Thread-1….show…. : 23
Thread-0….code : 22
Thread-1….show…. : 21
Thread-0….code : 20
Thread-1….show…. : 19
Thread-1….show…. : 18
Thread-0….code : 17
Thread-1….show…. : 16
Thread-0….code : 15
Thread-1….show…. : 14
Thread-0….code : 13
Thread-1….show…. : 12
Thread-0….code : 11
Thread-1….show…. : 10
Thread-0….code : 9
Thread-1….show…. : 8
Thread-0….code : 7
Thread-1….show…. : 6
Thread-0….code : 5
Thread-1….show…. : 4
Thread-0….code : 3
Thread-1….show…. : 2
Thread-0….code : 1
Thread-1….show…. : 0

出现了错票,说明不安全。
至少可以肯定的是同步函数用的锁不是obj。
那么同步函数的锁是什么呢??
函数需要被对象调用。那么函数都有一个所属对象引用。就是this。
所以同步函数使用的锁是this。

下面把锁obj改为this

class Ticket implements Runnable
{
    private  int tick = 100;
    Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(this)
                {
                    if(tick>0)
                    {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                    }
                }
            }
        }
        else
            while(true)
                show();
    }
    public synchronized void show()//this
    {
        if(tick>0)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
        }
    }
}


class  ThisLockDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();

    }
}

经过多次测试,没有发现错票!
说明同步函数使用的锁是this。

静态同步函数的锁是Clsaa对象

如果同步函数被静态修饰后,使用的锁是什么呢?

和上面一样,我们用程序来求解。

class Ticket implements Runnable
{
    private static  int tick = 100;
    //Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(this)
                {
                    if(tick>0)
                    {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                    }
                }
            }
        }
        else
            while(true)
                show();
    }
    public static synchronized void show()
    {
        if(tick>0)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
        }
    }
}


class  StaticMethodDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();


    }
}

运行结果又出现了0号票,又出现了错票,说明程序不安全,
说明静态函数的锁不是this。

通过验证,发现不在是this。因为静态方法中也不可以定义this。

静态进内存是,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
类名.class 该对象的类型是Class

下面来验证一下:
将this锁换成Ticket.class

class Ticket implements Runnable
{
    private static  int tick = 100;
    //Object obj = new Object();
    boolean flag = true;
    public  void run()
    {
        if(flag)
        {
            while(true)
            {
                synchronized(Ticket.class)
                {
                    if(tick>0)
                    {
                        try{Thread.sleep(10);}catch(Exception e){}
                        System.out.println(Thread.currentThread().getName()+"....code : "+ tick--);
                    }
                }
            }
        }
        else
            while(true)
                show();
    }
    public static synchronized void show()
    {
        if(tick>0)
        {
            try{Thread.sleep(10);}catch(Exception e){}
            System.out.println(Thread.currentThread().getName()+"....show.... : "+ tick--);
        }
    }
}


class  StaticMethodDemo
{
    public static void main(String[] args) 
    {

        Ticket t = new Ticket();

        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        t1.start();
        try{Thread.sleep(10);}catch(Exception e){}
        t.flag = false;
        t2.start();


    }
}

经过多次 运行,没有发现错票。

静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值