对象锁是指Java为临界区synchronized(Object)语句指定的对象进行加锁,对象锁是独占排他锁。对象锁用于程序片段或者method上,此时将获得对象的锁,所有想要进入该对象的synchronized的方法或者代码段的线程都必须获取对象的锁,如果没有,则必须等其他线程释放该锁。
对于对象锁来说,又可以分为两个,一个是方法锁,一个是同步代码块锁,我们重点要讲的就是同步代码块锁。
同步代码块锁主要是对代码块进行加锁,举个例子:
public class SynTest01 implements Runnable {
Object object = new Object();
public static void main(String[] args) throws InterruptedException {
SynTest01 syn = new SynTest01();
Thread thread1 = new Thread(syn);
Thread thread2 = new Thread(syn);
thread1.start();
thread2.start();
//线程1和线程2只要有一个还存活就一直执行
while (thread1.isAlive() || thread2.isAlive()) {}
System.out.println("main程序运行结束");
}
@Override
public void run() {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName()
+ "线程执行了run方法");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()
+ "执行2秒钟之后完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
在这个例子中,我们使用了synchronized锁住了run方法中的代码块。表示同一时刻只有一个线程能够进入代码块。就好比是去医院挂号,前面一个人办完了业务,下一个人才开始。
在这里面我们看到,线程1和线程2使用的是同一个锁,也就是我们new的Object。如果我们让线程1和线程2每一个人拥有一个锁对象呢?
public class SynTest01 implements Runnable {
Object object1 = new Object();
Object object2 = new Object();
public static void main(String[] args) throws InterruptedException {
SynTest01 syn = new SynTest01();
Thread thread1 = new Thread(syn);
Thread thread2 = new Thread(syn);
thread1.start();
thread2.start();
//线程1和线程2只要有一个还存活就一直执行
while (thread1.isAlive() || thread2.isAlive()) {}
System.out.println("main程序运行结束");
}
@Override
public void run() {
synchronized (object1) {
try {
System.out.println(Thread.currentThread().getName()
+ "线程执行了object1");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()
+ "执行object1完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (object2) {
try {
System.out.println(Thread.currentThread().getName()
+ "线程执行object2");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()
+ "执行object2完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
现在线程1和线程2每个人拥有一把锁,去访问不同的方法资源。这时候会出现什么情况呢?也就是说,相当于两个业务有俩窗口都可以办理,但是两个任务都需要排队办理。
同步代码块锁主要是对代码块进行加锁,此时同一时刻只能有一个线程获取到该资源,要注意每一把锁只负责当前的代码块,其他的代码块不管。当然,我们介绍的只是最简单的对象锁的使用,想要考验自己的小伙伴可以加大难度,去动力节点在线的视频课程找到更加复杂的实例来论证。
提枪策马乘胜追击04-21 20:01
代码小兵92504-17 16:07
代码小兵98804-25 13:57
杨晶珍05-11 14:54