synchronized详解
synchronized详解
1修饰类方法,锁定的是整个类
1.1同一类的不同对象,调用同一个静态同步方法,会等待锁释放
SynchronizedStatic静态同步方法
import java.util.Calendar;
public class SynchronizedStatic {
public synchronized static void testThreadA(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadA"+Calendar.getInstance().getTimeInMillis());
}
}
TestThreadA 线程类
public class TestThreadA extends Thread{
SynchronizedStatic ss;
public TestThreadA(SynchronizedStatic ss){
this.ss = ss;
}
public void run(){
ss.testThreadA();
}
}
测试类
public class TestSyn {
public static void main(String[] args) {
SynchronizedStatic ss = new SynchronizedStatic();
TestThreadA testThreadA1 = new TestThreadA(ss);
TestThreadA testThreadA2 = new TestThreadA(ss);
testThreadA1.start();
testThreadA2.start();
}
}
运行结果
testThreadA1550243750022
testThreadA1550243751043
(关于结果相差不止1秒,是我自己电脑配置不够好)
1.2同一类的不同对象,调用不同一个静态同步方法,会等待锁释放
增加一个TestThreadB ,同TestThreadA
public class TestThreadB extends Thread{
SynchronizedStatic ss;
public TestThreadB(SynchronizedStatic ss){
this.ss = ss;
}
public void run(){
ss.testThreadB();;
}
}
增加一个testThreadB方法
public class SynchronizedStatic {
public synchronized static void testThreadA(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadA"+Calendar.getInstance().getTimeInMillis());
}
public synchronized static void testThreadB(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadB"+Calendar.getInstance().getTimeInMillis());
}
}
主程序
public class TestSyn {
public static void main(String[] args) {
SynchronizedStatic ss = new SynchronizedStatic();
TestThreadA testThreadA1 = new TestThreadA(ss);
TestThreadA testThreadA2 = new TestThreadA(ss);
TestThreadB testThreadB1 = new TestThreadB(ss);
testThreadA1.start();
testThreadB1.start();
testThreadA2.start();
}
}
运行结果
testThreadA1550244372429
testThreadB1550244373454
testThreadA1550244374454
1.3同一对象,一个调用静态同步方法,一个调用非同步方法,不用等待锁释放
SynchronizedStatic新增方法
public static void testThreadC(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadC"+Calendar.getInstance().getTimeInMillis());
}
TestThreadC
public class TestThreadC extends Thread{
SynchronizedStatic ss;
public TestThreadC(SynchronizedStatic ss){
this.ss = ss;
}
public void run(){
ss.testThreadC();;
}
}
public class TestSyn {
public static void main(String[] args) {
SynchronizedStatic ss = new SynchronizedStatic();
TestThreadA testThreadA1 = new TestThreadA(ss);
TestThreadA testThreadA2 = new TestThreadA(ss);
TestThreadB testThreadB1 = new TestThreadB(ss);
TestThreadC testThreadC1 = new TestThreadC(ss);
testThreadA1.start();
testThreadC1.start();
testThreadB1.start();
testThreadA2.start();
}
}
运行结果
testThreadA1550244857145
testThreadC1550244857145
testThreadB1550244858165
testThreadA1550244859166
2修饰普通方法,锁定的是对象
2.1一个对象调用同一同步方法会等待锁释放
SynchronizedStatic 增加2个同步方法
public class SynchronizedStatic {
public synchronized void testThreadD(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadD"+Calendar.getInstance().getTimeInMillis());
}
public synchronized void testThreadE(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadE"+Calendar.getInstance().getTimeInMillis());
}
}
增加线程类TestThreadD ,(TestThreadE代码一样,不贴了 )
public class TestThreadD extends Thread{
SynchronizedStatic ss;
public TestThreadD(SynchronizedStatic ss){
this.ss = ss;
}
public void run(){
ss.testThreadD();;
}
}
测试代码
public class TestSyn {
public static void main(String[] args) {
SynchronizedStatic ss = new SynchronizedStatic();
// TestThreadA testThreadA1 = new TestThreadA(ss);
// TestThreadA testThreadA2 = new TestThreadA(ss);
// TestThreadB testThreadB1 = new TestThreadB(ss);
// TestThreadC testThreadC1 = new TestThreadC(ss);
// testThreadA1.start();
// testThreadC1.start();
// testThreadB1.start();
// testThreadA2.start();
TestThreadD testThreadA1 = new TestThreadD(ss);
TestThreadD testThreadA2 = new TestThreadD(ss);
testThreadA1.start();
testThreadA2.start();
}
}
运行结果
testThreadD1550245315866
testThreadD1550245316884
2.2一个对象调用不同同步方法会等待锁释放
public class TestSyn {
public static void main(String[] args) {
SynchronizedStatic ss = new SynchronizedStatic();
// TestThreadA testThreadA1 = new TestThreadA(ss);
// TestThreadA testThreadA2 = new TestThreadA(ss);
// TestThreadB testThreadB1 = new TestThreadB(ss);
// TestThreadC testThreadC1 = new TestThreadC(ss);
// testThreadA1.start();
// testThreadC1.start();
// testThreadB1.start();
// testThreadA2.start();
TestThreadD testThreadD1 = new TestThreadD(ss);
TestThreadD testThreadD2 = new TestThreadD(ss);
TestThreadE testThreadE1 = new TestThreadE(ss);
testThreadD1.start();
testThreadE1.start();
testThreadD2.start();
}
}
运行结果
testThreadD1550245435370
testThreadE1550245436388
testThreadD1550245437389
2.3同一对象,一个调用同步方法,另一方法调用非同步方法不需要等待释放锁
public class SynchronizedStatic {
public void testThreadF(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadF"+Calendar.getInstance().getTimeInMillis());
}
TestThreadD testThreadD1 = new TestThreadD(ss);
TestThreadD testThreadD2 = new TestThreadD(ss);
TestThreadE testThreadE1 = new TestThreadE(ss);
TestThreadF testThreadF1 = new TestThreadF(ss);
testThreadD1.start();
testThreadF1.start();
testThreadE1.start();
testThreadD2.start();
结果
testThreadF1550245592359
testThreadD1550245592359
testThreadE1550245593380
testThreadD1550245594381
3修饰代码块,锁定的也是对象
3.1当锁定是this,锁的是当前对象,与修饰的同步方法一样,会等待锁释放
public void testThreadG(){
synchronized(this){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadG"+Calendar.getInstance().getTimeInMillis());
}
}
public class TestThreadG extends Thread{
SynchronizedStatic ss;
public TestThreadG(SynchronizedStatic ss){
this.ss = ss;
}
public void run(){
ss.testThreadG();;
}
}
测试类
TestThreadG testThreadG = new TestThreadG(ss);
TestThreadD testThreadD1 = new TestThreadD(ss);
testThreadD1.start();
testThreadG.start();
结果
testThreadG1550246232928
testThreadD1550246233945
3.2当锁定是其他对象,不用等待锁释放
public void testThreadH(){
synchronized("abc"){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testThreadH"+Calendar.getInstance().getTimeInMillis());
}
}
测试代码
TestThreadG testThreadG = new TestThreadG(ss);
TestThreadD testThreadD1 = new TestThreadD(ss);
TestThreadH testThreadH = new TestThreadH(ss);
testThreadD1.start();
testThreadH.start();
testThreadG.start();
结果
testThreadH1550246385014
testThreadD1550246385014
testThreadG1550246386034
总结:synchronized修饰的是静态方法,那锁定的就是这个类。修饰的是非静态方法,锁定为对象。修饰代码块,锁定的是也是对象。一个对象只有一把锁。