2 java中synchronized的用法
1.用法1
public class Test{
public synchronized void print(){
....;
}
}
某线程执行print()方法,则该对象将加锁。其它线程将无法执行该对象的所有synchronized块。
2.用法2
public class Test{
public void print(){
synchronized(this){//锁住本对象
...;
}
}
}
同用法1, 但更能体现synchronized用法的本质。
3.用法3
public class Test{
private String a = "test";
public void print(){
synchronized(a){//锁住a对象
...;
}
}
public synchronized void t(){
...; //这个同步代码块不会因为print()而锁定.
}
}
执行print(),会给对象a加锁,注意不是给Test的对象加锁,也就是说 Test对象的其它synchronized方法不会因为print()而被锁。同步代码块执行完,则释放对a的锁。
为了锁住一个对象的代码块而不影响该对象其它 synchronized块的高性能写法:
public class Test{
private byte[] lock = new byte[0];
public void print(){
synchronized(lock){
...;
}
}
public synchronized void t(){
...;
}
}
4.静态方法的锁
public class Test{
public synchronized static void execute(){
...;
}
}
效果同
public class Test{
public static void execute(){
synchronized(TestThread.class){
...;
}
}
}
3 Java中的锁与排队上厕所。
锁就是阻止其它进程或线程进行资源访问的一种方式,即锁住的资源不能被其它请求访问。在JAVA中,sychronized关键字用来对一个对象加锁。比如:
public class MyStack {
int idx = 0;
char [] data = new char[6];
public synchronized void push(char c) {
data[idx] = c;
idx++;
}
public synchronized char pop() {
idx--;
return data[idx];
}
public static void main(String args[]){
MyStack m = new MyStack();
/**
下面对象m被加锁。严格的说是对象m的所有synchronized块被加锁。
如果存在另一个试图访问m的线程T,那么T无法执行m对象的push和
pop方法。
*/
m.pop();//对象m被加锁。
}
}
Java的加锁解锁跟多个人排队等一个公共厕位完全一样。第一个人进去后顺手把门从里面锁住,其它人只好排队等。第一个人结束后出来时,门才会打开(解锁)。轮到第二个人进去,同样他又会把门从里面锁住,其它人继续排队等待。
public synchronized void push(char c) {
this.notify(); //通知那些wait()的线程重新排队。注意:仅仅是通知它们重新排队。
Character charObj = new Character(c);
buffer.addElement(charObj);
}//执行完毕,释放锁。那些排队的线程就可以进来了。
再深入一些。
1.CountDownLatch 门插销计数器
1.启动线程,然后等待线程结束。即常用的主线程等所有子线程结束后再执行的问题。
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
final int count=10;
final CountDownLatch completeLatch = new CountDownLatch(count);//定义了门插销的数目是10