下面这段程序到底是锁定的tt对象呢?还是分别锁定的inc和dec对象呢?public class ThreadTest {
private int j; public static void main(String args[]) {
ThreadTest tt = new ThreadTest();
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
}
} private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
} private synchronized void dec() {
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
} class Inc implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
inc();
}
}
} class Dec implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
dec();
}
}
}
}
private int j; public static void main(String args[]) {
ThreadTest tt = new ThreadTest();
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(inc);
t.start();
t = new Thread(dec);
t.start();
}
} private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
} private synchronized void dec() {
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
} class Inc implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
inc();
}
}
} class Dec implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
dec();
}
}
}
}
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
等价于:
private void inc() {
synchronized(this){
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
}
也就是说,是锁定tt对象
synchronized void inc()是锁定方法,只有一个线程能进入方法
synchronized(this)是锁定对象,只有一个线程能使用对象,但是多个线程能同时进入inc方法,只是在synchronized(this)处发生解锁等待
public void run() {
synchronized(this) {
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(2000);
System.out.println(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
Test1 test=new Test1();
for(int i=0;i<10;i++) {
new Thread(test).start();
}
}
}
http://topic.csdn.net/u/20100514/12/06c5ce11-84a3-42ca-8744-8a83cca0530a.html?seed=1426370052&r=65431300#r_65431300
你这个例子是在Test1对象实例上加锁。
main方法中:
Test1 test=new Test1();
for(int i=0;i<10;i++) {
new Thread(test).start();
}
多个Thread共享一个test,test此时就是一个共享资源,因此10个Thread对象共享一个test,在test实例上加锁,同时只有1个Thread对象可以获得锁得以执行,因此这10个线程可以做到互斥。
你可以在代码里面输出线程的名字进行查看,只有一个执行完毕以后,下一个才开始执行。
你这个例子是在Test1对象实例上加锁。
main方法中:
Test1 test=new Test1();
for(int i=0;i<10;i++) {
new Thread(test).start();
}
多个Thread共享一个test,test此时就是一个共享资源,因此10个Thread对象共享一个test,在test实例上加锁,同时只有1个Thread对象可以获得锁得以执行,因此这10个线程可以做到互斥。
你可以在代码里面输出线程的名字进行查看,只有一个执行完毕以后,下一个才开始执行。
和在里面用synchronied(this)是一个效果的
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();内部类对象inc和dec的内部有一个私有成员,用来保存其外围类的实例,即tt。对应的run方法中调用的inc()和 dec()方法其实就是tt.inc()和 tt.dec()。所以两个线程获得对象锁是tt的锁。
一个简单的例子
synchronized void xxx() {
//一旦线程进入方法,其他线程就要等待
}
void xxx() {
//做一些额外处理
synchronized(this) {
//当某个线程进到这里,其他线程才会发生等待,在线程进入之前,多个线程可同时进入方法,处理上面的额外处理,如果没有上面的额外处理,从结果来说,和synchronized void xxx是一样的,但是从锁的角度来说是不一样的
}
}
aaaa;
bbbb;
cccc;
}与public void xxxx() {
synchronized(this) {
aaaa;
bbbb;
cccc;
}
}是一样的,没有区别
比如有某个入口,入口有两扇门,我们把它分为外门和内门,当锁外门的时候(即synchronized method),人是通不过入口进入里面的(即进不来方法内部),当锁内门的时候(即synchronized(this)),人也是通不过入口进入进入里面的,从结果来说,是一样的,都是人不能通过入口进入里面,但从锁的角度来说,是不一样的,因为锁外面,人还可以进入到外门和内门之间。当然,也可以同时锁两扇门,即两个synchronized同时用,结果也是一样的,但从锁的角度来说,也是不一样的,必须先获得第一个锁的权限,才有资格获得第二个所的机会。
另外,synchronized method的时候,当有线程进入该方法时,其他线程一样可以访问该对象的其他方法,可以自己写代码去test,我就不多说的了,以后可以自己在实践中多多体会。如果只知道的结果而不考虑其中的区别,那就忽略我所说的
通过 t = new Thread(xx) 后得到的一共4个线程尝试锁住 ThreadTest 对象,某个时刻获得 ThreadTest 对象的锁的话就可以执行 inc () 或 dec () 方法,要弄明白锁住哪个对象,其实你主要关注你需要保护哪个对象的状态(不是方法)。
但是我还是坚持synchronized method和synchronized(this)有区别,这是经验告诉了我,我虽然不能很好地解释,我自己查了一下《深入java虚拟机》第二版,第347-353页,上面有说两种的区别,功能上是一致的,即处理结果是一样的,但synchronized method更高效,有兴趣的人自己去看吧
只是这个方法中的部分几行代码需要进行同步处理,并不需要将整个方法锁住。