原因
书看多了、视频看多了。感觉自己懂了,其实没懂。抽时间整理一下。
锁
我们第一个反应都是synchronize、ReentrantLock 两个可重入锁,然后优缺点都能说一大堆,各种资料中也有。今天我就简单的实践下,这个锁具体竞争资源是怎么样的。
- 第一种 synchronize(this) 锁当前实例,Demo是没一个线程都创建一次的话,那么是不安全的
public class Demo implements Runnable {
public static void main(String[] args) {
Demo demo = new Demo();
for (int i = 0;i<10000;i++){
Thread t1 = new Thread(demo);
t1.setName(String.valueOf(i));
t1.start();
}
}
@Override
public void run() {
synchronized (this) {
String name = Thread.currentThread().getName();
Text.source++;
System.out.println(name + ":" + Text.source);
}
}
}
class Text{
static int source = 0;
}
- 第一种 synchronize(this) 锁当前实例,如果Demo是唯一资源的话,那么就是线程安全的。
public class Demo implements Runnable {
Demo demo = new Demo();
public static void main(String[] args) {
for (int i = 0;i<10000;i++){
Thread t1 = new Thread(demo);
t1.setName(String.valueOf(i));
t1.start();
}
}
@Override
public void run() {
synchronized (this) {
String name = Thread.currentThread().getName();
Text.source++;
System.out.println(name + ":" + Text.source);
}
}
}
class Text{
static int source = 0;
}
- synchronize(Object.class) ,线程安全的,因为Object.class只有一份,属于可以竞争
public class Demo implements Runnable {
Demo demo = new Demo();
public static void main(String[] args) {
for (int i = 0;i<10000;i++){
Thread t1 = new Thread(demo);
t1.setName(String.valueOf(i));
t1.start();
}
}
@Override
public void run() {
synchronized (Object.class) {
String name = Thread.currentThread().getName();
Text.source++;
System.out.println(name + ":" + Text.source);
}
}
}
class Text{
static int source = 0;
}
- ReentrantLock 同样锁的是当前实例,lock需要独一份,才能完成锁。线程安全
public class Demo implements Runnable {
ReentrantLock reentrantLock;
public Demo(ReentrantLock reentrantLock){
this.reentrantLock = reentrantLock;
}
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
for (int i = 0; i < 10000; i++) {
Demo demo = new Demo(reentrantLock);
Thread t1 = new Thread(demo);
t1.setName(String.valueOf(i));
t1.start();
}
}
@Override
public void run() {
reentrantLock.lock();
String name = Thread.currentThread().getName();
Text.source++;
System.out.println(name + ":" + Text.source);
reentrantLock.unlock();
}
}
class Text {
volatile static int source = 0;
}