经常在java中需要使用到多线程,有时候也需要对多线程访问的同一个方法进行限制同一时间段只能一个线程操作,这个时候可以使用synchronized 语句,不过java也提供了一个Lock接口来实现锁的功能。这个看需要使用吧。
synchronized 线程同步
synchronized 经常用在两个或多个线程运行时需要访问同一个方法,或是同一个代码块。
比如
A:{statement 语句块}
多个线程访问同一个代码块的时候,如果没有限制。那么计算机执行线程的时候,可能会有多个线程同时访问A代码块内部的语句,势必会造成A代码块内部语句执行效果达不到理想状态。有时候会出现数据被多个线程同时修改。
同样除了代码块,方法部分也是。
Synchronized语句就是用来解决这个问题。
Synchronized的作用就像是一把锁栓,Synchronized()里面可以放一个监听对象,我们可以把他想像为一把锁,把Synchronized语句放在代码块前面,可以为代码块加一个监听对象。
多线程在调用使用了Synchronized语句的代码块时,每个线程调用,Synchronized就会个这个线程一个句柄,比喻为钥匙,当其他线程再来想访问的时候,就必须得到这个钥匙,而Synchronized语句只有在刚开始的得到钥匙的线程执行外代码块语句后,才会重新得到代码块中执行线程给的句柄(钥匙).这样就避免多个线程同时操作同一个代码块或者方法。
方法部分使用Synchronized规范。
Public void synchronized print(){}
这个Synchronized对象使用的对象就是调用这个方法的类,要线程获取句柄的对象是方法调用的对象,如果是静态方法,可以使用调用静态方法的类.class返回的字节码对象。
public class Synchronizeddemo {
private static int size=0;//一个静态成员变量,用来多线程同时操作
public static void print(String name)
{
for(int i=0;i<20;++i)
{
synchronized(Synchronizeddemo.class){
//使用静态类字节码对象来做加锁对象,只有执行线程退出代码块,其他线程能执行这段代码块,
System.out.println(name+":size is:"+size++);
}
}
}
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
print("thread");
}
}).start();//new一个线程来同时执行相同的方法
print("main");
}
}
同样synchronized也可以直接加在方法标识符上使用。
public static synchronized void print(String name)
{
for(int i=0;i<20;++i)
{
//将synchronized加在方法上
System.out.println(name+":size is:"+size++);
}
}
效果和代码块同理,不过加在方法上,在有一个线程执行了这个方法时,其他线程不能执行这个方法内部的代码。