您的位置:首页 > 职场人生

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

2015-03-28 13:52 295 查看
 ——- 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
ceaa
….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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程