原文:https://www.cnblogs.com/QQParadise/articles/5059824.html
使用
synchronized
写个同步方法,很轻松的能解决一些多线程问题。但是synchronized
究竟锁住的是类(全局锁)还是对象?只要加上synchronized
就能保证线程安全吗?
demo1 (三个线程 操作三个 Sync 对象)
class Sync {
public synchronized void test() {
System.out.println(Thread.currentThread().getName() + "开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
运行结果
Thread-2开始..
Thread-1开始..
Thread-0开始..
Thread-2结束..
Thread-1结束..
Thread-0结束..
可以看到三个线程,操作三个对象,这时候 synchronized
并不起作用...
改造
- 使用
synchronized(this){}
,这边我直接剧透了,结果一样...
demo2 (三个线程 操作同一个 Sync 对象)
class Sync {
public void test() {
synchronized(this) {
System.out.println(Thread.currentThread().getName() + "开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束..");
}
}
}
class MyThread extends Thread {
private Sync sync;
public MyThread(Sync sync) {
this.sync = sync;
}
public void run() {
sync.test();
}
}
public class Main {
public static void main(String[] args) {
Sync sync = new Sync();
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread(sync);
thread.start();
}
}
}
运行结果
Thread-0开始..
Thread-0结束..
Thread-2开始..
Thread-2结束..
Thread-1开始..
Thread-1结束..
改造
- 使用
synchronized
修饰方法,结果一样...
小结
从上面两个例子来看,其实 synchronized
修饰方法 和 synchronized(this){}
锁的是对象
demo3 synchronized 全局锁(锁类)
class Sync {
public void syncTest() {
// 或者是 this.getClass()
synchronized (Sync.class) {
System.out.println(Thread.currentThread().getName() + "开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束..");
}
}
public static synchronized void staticTest() {
System.out.println(Thread.currentThread().getName() + "开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "结束..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.syncTest();
// Sync.staticTest();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
分别执行两个方法,这时候都实现了全局锁(锁住了类)
Thread-0开始..
Thread-0结束..
Thread-2开始..
Thread-2结束..
Thread-1开始..
Thread-1结束..
总结
-
synchronized
修饰方法 和synchronized(this){}
锁的是对象 -
static synchronized
修饰方法 和synchronized(this.getClass()){}
是全局锁
网友评论