论坛首页 编程语言技术论坛

Java中同步代码块的疑惑

浏览 10703 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-24   最后修改:2012-04-24

在Java同步代码块中可以指定一个object作为同步锁,但是当我指定的object不一样的时候,产生了不一样的输出,不知道什么原因,下面是示例代码:

import java.util.logging.Level;
import java.util.logging.Logger;

class CallMe {
	public void demoMethod(String message) {
		try {
			System.out.print("{");
			Thread.sleep(1);
			System.out.print(message);
			Thread.sleep(1);
			System.out.println("}");
		} catch (InterruptedException ex) {
			Logger.getLogger(CallMe.class.getName()).log(Level.SEVERE, null, ex);
		}
	}
}

class NewThread extends Thread {
	CallMe callme;
	String name;
	CallMe callme1 = new CallMe();

	public NewThread(String x, CallMe callme) {
		this.callme = callme;
		name = x;
	}

	public void run() {
		synchronized (callme1) {
			callme.demoMethod(name);
		}
	}
}

public class ThreadDemo {
	public static void main(String args[]) throws InterruptedException {
		CallMe callme = new CallMe();
		NewThread nt1 = new NewThread("one", callme);
		NewThread nt2 = new NewThread("two", callme);
		NewThread nt3 = new NewThread("three", callme);
		nt1.start();
		nt2.start();
		nt3.start();
		nt1.join();
		nt2.join();
		nt3.join();
	}
}
 
输出结果为:

{{{threeonetwo}

}

}

 

但是对于下面的代码(注意只有那个synchronized(callme)不一样):

import java.util.logging.Level;
import java.util.logging.Logger;

class CallMe {
	public void demoMethod(String message) {
		try {
			System.out.print("{");
			Thread.sleep(1);
			System.out.print(message);
			Thread.sleep(1);
			System.out.println("}");
		} catch (InterruptedException ex) {
			Logger.getLogger(CallMe.class.getName()).log(Level.SEVERE, null, ex);
		}
	}
}

class NewThread extends Thread {
	CallMe callme;
	String name;
	CallMe callme1 = new CallMe();

	public NewThread(String x, CallMe callme) {
		this.callme = callme;
		name = x;
	}

	public void run() {
		synchronized (callme) {
			callme.demoMethod(name);
		}
	}
}

public class ThreadDemo {
	public static void main(String args[]) throws InterruptedException {
		CallMe callme = new CallMe();
		NewThread nt1 = new NewThread("one", callme);
		NewThread nt2 = new NewThread("two", callme);
		NewThread nt3 = new NewThread("three", callme);
		nt1.start();
		nt2.start();
		nt3.start();
		nt1.join();
		nt2.join();
		nt3.join();
	}
}
 

输出结果为:

{one} 

{two} 

{three}

 

   发表时间:2012-04-24  
不同的对象,不同的实例,不同的锁。当前对象作为锁。
0 请登录后投票
   发表时间:2012-04-25   最后修改:2012-04-25
锁同一个对象才能同步
0 请登录后投票
   发表时间:2012-04-28  
第一块代码,不存在锁资源竞争,就是说执行顺序随机。
第二块,竞争同一资源。
0 请登录后投票
   发表时间:2012-04-28  
第一段代码21行,加static限制,两段代码的输出就一致了
0 请登录后投票
   发表时间:2012-04-29  
前者是错误用法
0 请登录后投票
   发表时间:2012-04-29  
第一段代码中,每一个线程使用中,使用的锁都不同,所以不存在资源竞争,也就不存在互斥,所以不存在同步;第二段代码中,三个线程使用的是同一个锁,线程执行的时候,对于同步块会有互斥现象,所以可以实现同步。
0 请登录后投票
   发表时间:2012-05-03  
第一个代码块中,callme1是实例变量,每一个对象都有他自己的实现,所以用它做锁没有效果;
第二个代码块中,三个对象共享一个callme,所以用它做锁会产生竞争.
0 请登录后投票
   发表时间:2012-05-03  
同意
humor200
的说法
0 请登录后投票
   发表时间:2012-05-03  
my_queen 写道
第一个代码块中,callme1是实例变量,每一个对象都有他自己的实现,所以用它做锁没有效果;
第二个代码块中,三个对象共享一个callme,所以用它做锁会产生竞争.


恩, 但是LZ的这个例子对输出的顺序根本没有任何限制,两个例子的输出都是无顺序保证的
0 请登录后投票
论坛首页 编程语言技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics