写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
概念:
synchronized 用来做线程同步;
对象锁 与 类锁:
synchronized加到非静态方法或代码块时,给对象加锁,多个线程执行该对象的同步方法会互斥
多个对象执行对象中的同步方法不会互斥。
synchronized加到静态方法或类时,锁的是这个类,多个线程多个对象执行对象中的同步方法时都会互斥
对以上说明通过代码来演示以便方便理解。
1.验证修饰非静态方法
public class SynchronizedTest {
public static void main(String[] args) {
SynchronizedTest test = new SynchronizedTest();
new Thread(new Runnable() {
@Override
public void run() {
test.test1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test.test1();
}
}).start();
}
public synchronized void test1(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
public class SynchronizedTest {
public static void main(String[] args) {
SynchronizedTest test = new SynchronizedTest();
new Thread(new Runnable() {
@Override
public void run() {
test.test1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test.test2();
}
}).start();
}
public synchronized void test1(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
public synchronized void test2(){
synchronized (this){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
}
运行结果相同如下:
表名:两个线程执行的同一对象中的同步方法(同步代码块),会互斥,两个线程执行的同一对象中两个不同的同步方法(同步代码块),还是会互斥
public class SynchronizedTest {
public static void main(String[] args) {
SynchronizedTest test = new SynchronizedTest();
SynchronizedTest test1 = new SynchronizedTest();
new Thread(new Runnable() {
@Override
public void run() {
test.test1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test1.test1();
}
}).start();
}
public synchronized void test1(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
运行结果相同如下:
表名:两个线程分别执行不同对象中的同步方法(同步代码块)不会互斥。
总结:说明synchronized修饰非静态方法(代码块)时,是给对象加锁。
2.验证修饰静态方法
public class SynchronizedTest {
public static void main(String[] args) {
SynchronizedTest test = new SynchronizedTest();
SynchronizedTest test1 = new SynchronizedTest();
new Thread(new Runnable() {
@Override
public void run() {
test.test1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
test1.test1();
}
}).start();
}
public static synchronized void test1(){
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
运行结果如下:
表名:两个线程分别执行不同对象中的同步方法(同步代码块)仍然会互斥。
总结:说明synchronized修饰静态方法(代码块)时,锁的是这个类。既然修饰静态方法时锁的是类,多个线程执行类中同步方法时会互斥,那么直接将synchronized加到类上,锁这个类肯定同修饰静态方法效果一样,都互斥。