java同步:synchronized

来源:互联网 发布:淘宝店铺降权查询 编辑:程序博客网 时间:2024/06/03 04:44

一、名词解释

synchronized可用来给对象的方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同时最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等到当前线程执行完这个代码块以后才能够执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程任然可以访问该object中的非加锁代码块。

二、加锁的两种方式

1、同步方法:
public synchronized void setData(String data){操作共享数据}
2、同步代码块:必须是同一把锁
synchronized(任意对象(锁)){       代码块中存放共享数据的代码}

三、具体实现

public static void main(String[] args) {final MySynchronized mySynchronized = new MySynchronized();final MySynchronized mySynchronized2 = new MySynchronized();new Thread("thread1") {public void run() {synchronized (mySynchronized) {try {System.out.println(this.getName()+" start");int i =1/0;   //如果发生异常,jvm会将锁释放Thread.sleep(5000);System.out.println(this.getName()+"醒了");System.out.println(this.getName()+" end");} catch (InterruptedException e) {e.printStackTrace();}}}}.start();new Thread("thread2") {public void run() {synchronized (mySynchronized) {         //争抢同一把锁时,线程1没释放之前,线程2只能等待//synchronized (mySynchronized2) {    //如果不是一把锁,可以看到两句话同时打印System.out.println(this.getName()+" start");System.out.println(this.getName()+" end");}}}.start();}

四、synchronized缺陷

如果一段代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1)、获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)、线程执行发生异常,此时JVM会让线程自动释放锁。
1、如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是有没有释放锁,其他线程只能够等待,试想一下,这多么影响程序的执行效率。
替换方法:因此需要一种机制可以不让等待的线程一直无限期的等待下去(比如只等待一定的时间或者能够响应中断),通过Lock可以办到。
2、当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作是不会发生冲突的。
分析:若采用synchronized关键字来实现的话,就会导致一个问题:
如果多个线程只是进行读操作,当一个线程进行读操作时,其他线程只能等待无法进行读操作。
替换方法:因此就需要一种机制来使多个线程只是进行读操作时,线程之间不会发生冲突,通过Lock可以办到。
另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。


1 0
原创粉丝点击