在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。Synchronized既可以对代码块使用,也可以加在整个方法上。
关键是,不要认为给方法或者代码段加上synchronized就万事大吉,看下面一段代码:
class Sync { public synchronized void test() { class MyThread extends Thread { public void run() { public class Main { public static void main(String[] args) { |
运行结果:
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
可以看出来,上面的程序起了三个线程,同时运行test方法,虽然test方法加上了synchronized,但是还是同时运行起来,貌似synchronized没起作用。
将test方法改成如下:
public void test() { synchronized(this){ System.out.println("test开始.."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("test结束.."); } } |
运行结果:
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
一切还是这么平静,没有看到synchronized起到一丝作用。
实际上,synchronized(this)以及非static的synchronized方法(至于static synchronized方法请往下看),只能防止多个线程同时执行同一个对象的这个代码段。
为什么会这样呢,回到本文的题目上:Java线程同步:synchronized锁住的是代码还是对象。答案是:synchronized锁住的是括号里的对象,而不是代码。对于非静态的synchronized方法,锁的就是对象本身也就是this。
当synchronized锁住一个对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的。