lock对象应该如何声明?是全局变量还是在需要同步的代码块声明局部变量?
带着这个疑问我自己实际操作了一把,代码如下:
第一种情况:lock为全局变量,需要同步的方法所在的类在使用时总是新建new
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
Lock lock = new ReentrantLock();
public void test1(String name){
// Lock lock = new ReentrantLock();
System.out.println("lock:"+lock.hashCode());
lock.lock();
for (int i = 0; i < 100; i++) {
System.out.println("当前线程=========="+name+":"+i);
}
lock.unlock();
}
public static void main(String[] args) {
// TestLock testLock = new TestLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
thread1.start();
thread2.start();
}
}
运行结果:lock对象不是同一个,无法实现多线程同步。
第二种情况:lock对象总是新建,同步方法所在类的对象是同一个
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
// Lock lock = new ReentrantLock();
public void test1(String name){
Lock lock = new ReentrantLock();
System.out.println("lock:"+lock.hashCode());
lock.lock();
for (int i = 0; i < 100; i++) {
System.out.println("当前线程=========="+name+":"+i);
}
lock.unlock();
}
public static void main(String[] args) {
TestLock testLock = new TestLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
// TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
// TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
thread1.start();
thread2.start();
}
}
运行结果:lock对象不是同一个,无法实现多线程同步。
第三种情况:两者都总是新建
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
// Lock lock = new ReentrantLock();
public void test1(String name){
Lock lock = new ReentrantLock();
System.out.println("lock:"+lock.hashCode());
lock.lock();
for (int i = 0; i < 100; i++) {
System.out.println("当前线程=========="+name+":"+i);
}
lock.unlock();
}
public static void main(String[] args) {
// TestLock testLock = new TestLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
thread1.start();
thread2.start();
}
}
运行结果:lock对象不是同一个,无法实现多线程同步。
第四种情况:两个都保证多线程情况下拿到的是同一个对象
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
Lock lock = new ReentrantLock();
public void test1(String name){
// Lock lock = new ReentrantLock();
System.out.println("lock:"+lock.hashCode());
lock.lock();
for (int i = 0; i < 100; i++) {
System.out.println("当前线程=========="+name+":"+i);
}
lock.unlock();
}
public static void main(String[] args) {
TestLock testLock = new TestLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
// TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
// TestLock testLock = new TestLock();
testLock.test1(Thread.currentThread().getName());
}
});
thread1.start();
thread2.start();
}
}
运行结果:实现多线程同步
经过实测,lock锁实现同步需要同时获取lock对象和需要同步代码的对象实例,多线程获取的两个实例对象都必须是相同的,否则无法实现同步。
实现多线程同步只需要lock对象是同一个,为什么还要保证同步方法所在类的对象也是同一个?
lock锁生效前提是多线程情况下所有线程拿到的lock对象都是同一个;lock对象是同步方法所在类的全局变量,如果同步方法所在类的对象不是同一个,得到的lock对象也不是同一个。
以上均属于个人理解,不对之处可评论指出。