java的锁的机制

来源:互联网 发布:java字符串补零 编辑:程序博客网 时间:2024/05/01 07:51


 

 

 

---------------------------------------------------------------------------------------------------------------------------------

上面的代码中,创建一个类实现一个方法,然后在实现Runable接口的两个线程中同时调用这个方法。可是却出现了和想的不一样的地方,

image

本应该是num依次递增的才对啊,为什么会出现这样的情况呢,且看我的分析。

分析如下:两个线程启动了,第一个t1线程使用类里面的show()方法,num递增一,变为1,然后休眠,t2调用show(),这时num再次递增1,变为了二。这时,t1结束休眠继续执行,打印出第一行,然后t2结束休眠,打印出第二行,这就和上面的运行结果符合了。问题随之而来,这样的打印并不正确,因为是t1先调用的show()方法,t2后调用的show()方法,打印的时候应该是:t1我是第1个调用该方法的线程,t2我是第2个调用该方法的线程才对啊,呵呵,这才是这次试验的目的所在。

对于执行同一段代码的两个线而言,这样运行时很危险的,如果一个线程去写文件,而另一个线程也去写文件,写的顺序不一样,文本写出来,就会不知道该怎么去读写好的这个文本文件了,所以,必须先让一个程序去执行完这段代码之后,另一个线程才能执行,这样写的顺序才不会乱,文件才有意义。既然这样该怎么样去控制呢。java里面提供了一个锁的机制,synchronized ,使用这个锁的机制,可以保证t1执行完这段代码之后(这其中不管t1是否挂起或者睡眠,执行完成代码)t2线程才能去执行。synchronized 的使用方法有两种,一种是

public synchronized void function(){synchronized (this){code;}},public synchronized  void  function(){code;},但是这两种是有区别的,第二种把synchronized 当作方法的修饰字,实际上是把方法定义成了一个代码块,这可能会使持有锁定的时间比实际长,影响了程序的运行效率。

另外,关于线程的同步还有一个方法,查阅java—jdk文档可以知道,volatile,这是一个静态的方法,关于介绍jdk文档是这么说的。

image

使用synchronized 虽然能有效避免同步的问题虽然能避免上述的问题的发生,但是会造成死锁现象,下回分解。