[Java并发编程] synchronized(this)

时间:2021-09-09 15:56:05


1、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

2、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问object中的非synchronized(this)同步代码块。

3、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其他synchronized(this)同步代码块得访问将被阻塞。

4、第三个例子同样适用其他同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其他线程对该object对象所有同步代码部分的访问都将被暂时阻塞。

5、以上规则对其他对象锁同样适用

 

一、

  public class Thread1 implements Runnable{  

/**
* 一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。
* 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块
* @param args
*/
public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread ta=new Thread(t1,"A");
Thread tb=new Thread(t1,"B");
ta.start();
tb.start();
}

@Override
public void run() {
synchronized(this){
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+" synchronized loop "+i);
}
}
}

}

 执行结果:

     A synchronized loop 0
     A synchronized loop 1
     A synchronized loop 2
     A synchronized loop 3
     A synchronized loop 4
     B synchronized loop 0
     B synchronized loop 1
     B synchronized loop 2
     B synchronized loop 3

     B synchronized loop 4

二、

    package review.testSynchronized;  

public class Thread2 implements Runnable {

/**
* 然而,当一个线程访问object的一个synchronized(this)同步代码块时,
* 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
* @param args
*/
public static void main(String[] args) {
final Thread2 myt2=new Thread2();
Thread t1=new Thread(
new Runnable(){
public void run(){
myt2.m4t1();
}
},"t1"
);
Thread t2=new Thread(
new Runnable(){
public void run(){
myt2.m4t2();
}
},"t2"
);
t1.start();
t2.start();
}
public void m4t1(){
synchronized(this){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void m4t2(){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {

}

}

 执行结果:

     t1 : 4
     t1 : 3
     t1 : 2
     t1 : 1
     t2 : 4
     t2 : 3
     t2 : 2
     t2 : 1
     t2 : 0
     t1 : 0


 

三、

    package review.testSynchronized;  

public class Thread3 {

/**
* 三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,
* 其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
* @param args
*/
public static void main(String[] args) {
final Thread3 myt2=new Thread3();
Thread t1=new Thread(
new Runnable(){
public void run(){
myt2.m4t1();
}
},"Thread3_t1"
);
Thread t2=new Thread(
new Runnable(){
public void run(){
myt2.m4t2();
}
},"Thread3_t2"
);
t1.start();
t2.start();
}
public void m4t1(){
synchronized(this){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void m4t2(){
synchronized(this){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
}

 执行结果:

     Thread3_t1 : 4
     Thread3_t1 : 3
     Thread3_t1 : 2
     Thread3_t1 : 1
     Thread3_t1 : 0
     Thread3_t2 : 4
     Thread3_t2 : 3
     Thread3_t2 : 2
     Thread3_t2 : 1
     Thread3_t2 : 0 

 

四、

    package review.testSynchronized;  

public class Thread4 {

/**
* 四、第三个例子同样适用其它同步代码块。
* 也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。
* 结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
* @param args
*/
public static void main(String[] args) {
final Thread4 myt4=new Thread4();
Thread t1=new Thread(
new Runnable(){
public void run(){
myt4.m4t1();
}
},"Thread4_t1"
);
Thread t2=new Thread(
new Runnable(){
public void run(){
myt4.m4t2();
}
},"Thread4_t2"
);
t1.start();
t2.start();
}
public void m4t1(){
synchronized(this){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void m4t2(){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}  

执行结果:

     Thread4_t1 : 4
     Thread4_t1 : 3
     Thread4_t1 : 2
     Thread4_t1 : 1
     Thread4_t1 : 0
     Thread4_t2 : 4
     Thread4_t2 : 3
     Thread4_t2 : 2
     Thread4_t2 : 1
     Thread4_t2 : 0

 

 五、

    package review.testSynchronized;  

public class Thread5 {

/**
* @param args
*/
public static void main(String[] args) {
final Thread5 myt5=new Thread5();
final Inner inner=myt5.new Inner();
Thread t1=new Thread(new Runnable(){
public void run(){
myt5.m4t1(inner);
}
},"Thread5_t1"
);
Thread t2=new Thread(new Runnable(){
public void run(){
myt5.m4t2(inner);
}
},"Thread5_t2"
);
t1.start();
t2.start();
}
class Inner{
private void m4t1(){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":Inner.m4t1()="+i);
try{
Thread.sleep(500);
}catch(Exception e){

}
}
}
private void m4t2(){
int i=5;
while(i-->0){
System.out.println(Thread.currentThread().getName()+":Inner.m4t2()="+i);
try{
Thread.sleep(500);
}catch(Exception e){
}
}
}
}
private void m4t1(Inner inner){
synchronized(inner){//使用对象锁
inner.m4t1();
}
}
private void m4t2(Inner inner){
inner.m4t2();
}

}

执行结果:

(尽管t1获得了对Inner的对象锁,但由于线程t2 访问的是同一个inner的非同步部分。所所以两个线程互不干扰)

     Thread5_t1:Inner.m4t1()=4
     Thread5_t2:Inner.m4t2()=4
     Thread5_t2:Inner.m4t2()=3
     Thread5_t1:Inner.m4t1()=3
     Thread5_t2:Inner.m4t2()=2
     Thread5_t1:Inner.m4t1()=2
     Thread5_t2:Inner.m4t2()=1
     Thread5_t1:Inner.m4t1()=1
     Thread5_t1:Inner.m4t1()=0
     Thread5_t2:Inner.m4t2()=0

 

现在在Inner.m4t2()前面加上synchronized:

(尽管t1与t2访问了同一个对象中两个毫不相干的部分,但因为t1先获得了对对象Inner的对象锁,所以t2对Inner.m4t2()的访问也被阻塞,因为m4t2()是Inner中的一个同步方法)

     Thread5_t1:Inner.m4t1()=4
     Thread5_t1:Inner.m4t1()=3
     Thread5_t1:Inner.m4t1()=2
     Thread5_t1:Inner.m4t1()=1
     Thread5_t1:Inner.m4t1()=0
     Thread5_t2:Inner.m4t2()=4
     Thread5_t2:Inner.m4t2()=3
     Thread5_t2:Inner.m4t2()=2
     Thread5_t2:Inner.m4t2()=1
     Thread5_t2:Inner.m4t2()=0