同步是处理多线程时经常用的方法。下面谈一下自己的理解。
什么时候使用synchronized关键字:
不论什么时候,只要您将编写的变量接下来可能被另一个线程读取,或者您将读取的变量最后是被另一个线程写入的,那么您必须进行同步。
先从线程说起。
新任务的建立可以继承自Runnable或者是Thread,一般来说是继承Runnable,
因为1,它是一个接口,可以不浪费java中的继承类。2它只有一个run方法需要继承,少了其他的一些杂七杂八的东西。
参照<java编程思想>里面的说法,我们称实现Runnable接口的类为任务类。
其实可以这样理解,任务类首先是java中一个类,它和普通类不同的地方就在于它可以不在主线程中执行,能够挂载到另一个线程中来执行。
需要明确一点任务和同步是两个概念,千万不能混淆。任务中可以包含同步的代码,也可以不包含。也就是run方法中可以有synchronized代码块,也可以没有。
每一个对象实例都相当于一个房子,多个对象实例相当于多个房子
理解synchronized代码块要把他理解成为一个带锁的房间。调用该对象方法的线程相当于一个想进入房间的人。
synchronized上可以安装大锁,小锁,原子锁等等各种不同类型的锁。对应于不同的锁类型,比如实例锁,对象锁,静态锁。
实例锁:byte[] a = new byte[0]; object a = new object();
对象锁: this ,或者是synchronized方法块
静态锁: 类名.class或者是 静态synchronized方法块。
锁没有大小之分,只有类型不同。
synchronized分为语句块和方法块,分别对应于上锁的屏风和上锁的门。
没有synchronized相当于没有锁的门,任何线程,也就是任何人都可以进去。
synchronized中的wait相当于把钥匙放到客厅,然后等待再次拿到钥匙。
synchronized中的notify相当于把钥匙放回客厅。
需要注意的是,当一个线程执行synchronized方法时,别的synchronized方法也都会阻塞。相当于这个钥匙对所有的带锁的房间都适用,一个人拿到钥匙后,另一个人就需要在那里等待。前提是synchronized使用的是同一个锁。
synchronized锁的是对象的意思是:一旦进入一个synchronized语句块或方法,别的synchronized语句块和方法将阻塞。知道上一个synchronized执行完成或者在其中使用wait方法,主动放弃钥匙。
实例锁使用byte[] a = new byte[0].比使用object a = new object好。前者三行操作,后者7行操作。
参考下面的博文:
http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html