synchronized是java内置关键字,解决共享数据冲突,是一个可重入锁
synchronized( 需要一个任意的对象(锁) ){
代码块中放操作共享数据的代码
多个线程不能同时进行的部分
}
锁就是一个标记
如果用的不是一把锁,则两个线程互不相干
java中的每一个对象都可以是一个锁
如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)线程执行发生异常,此时JVM会让线程自动释放锁。
synchronized在JVM里的实现原理:
代码块同步是使用monitorenter(监视器进入,获取锁)和monitorexit(监视器退出,释放锁)指令实现的
synchronized用的锁是存在对象头里
Demo
public class MySynchronized {
public static void main(String[] args) {
final MySynchronized mySynchronized = new MySynchronized();
final MySynchronized mySynchronized2 = new MySynchronized();
new Thread("thread1") {
public void run() {
synchronized (mySynchronized) {
try {
System.out.println(this.getName()+" start");
int i =1/0; //如果发生异常,jvm会将锁释放
Thread.sleep(5000);
System.out.println(this.getName()+"醒了");
System.out.println(this.getName()+" end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread("thread2") {
public void run() {
synchronized (mySynchronized) { //争抢同一把锁时,线程1没释放之前,线程2只能等待
// synchronized (mySynchronized2) { //如果不是一把锁,可以看到两句话同时打印
System.out.println(this.getName()+" start");
System.out.println(this.getName()+" end");
}
}
}.start();
}
}
转载请注明:汪明鑫的个人博客 » synchronized
说点什么
您将是第一位评论人!