synchronized同步代码块

/ 多线程 / 没有评论 / 316浏览

我们知道synchronized关键字可以在方法中修饰,当synchronized关键字修饰方法时,当前只能有一个线程执行此方法,其它线程只能等待,这也是synchronized关键字在方法上修饰的弊端 ,因为每一个线程都要频繁的获取锁,如果获取不到就等待,这样会严重影响程序的效率。所以我们尽量不用synchronized关键字在方法上修饰,这个锁实在是太重了。其实synchronized关键字还可以独立的存在,这就是synchronized同步代码块。请看下面的代码。

/**
* 商品信息
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 11:51
* @since 1.0.0
*/
public class Goods extends Thread {

/**
* 商品库存
*/
private int stock = 5;

@Override
public void run() {
synchronized (this) {
stock--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("购买用户: %s 当前库存: %s", Thread.currentThread().getName(), stock));
}
}
}
/**
* 用户购买
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-13 11:57
* @since 1.0.0
*/
public class GookdsTest {
public static void main(String[] args) throws InterruptedException {
Goods goods = new Goods();
Thread ming = new Thread(goods, "小明");
Thread hong = new Thread(goods, "小红");
ming.start();
hong.start();
}
}
购买用户: 小明 当前库存: 4
购买用户: 小红 当前库存: 3

我们看synchronized同步代码块和synchronized直接修饰方法是一样的,都可以保证线程安全。唯一的区别就是synchronized同步代码块需要传入一个参数。这个参数也就是当前synchronized同步代码块的锁。如果传this也就是将当前对象当做synchronized同步代码块的锁,当然我们也可以传入其它的对象当作锁。用synchronized同步代码块来解决线程安全问题时,它创建的锁的粒度比较小,因为不用每一次进方法时都要判断,只要执行到synchronized同步代码块时在判断就可以了,所以会提升程序运行的性能,在日常开发中推荐使用synchronized同步代码块。