您的位置:首页 > 编程语言

并发学习笔记(二):synchronized代码块

2016-03-29 23:27 344 查看
需求:创建一个服装店对象实例,用两个线程模拟两个人同时进店挑衣服->试衣服->买衣服的过程。

代码:

public class ShopDemo {
public static void main(String args[]){
Shop shop = new Shop();
Thread t1 = new Thread(shop);
Thread t2 = new Thread(shop);

t1.start();
t2.start();
}
}

class Shop implements Runnable{
public void run(){
Thread t = Thread.currentThread();
System.out.println(t+"..."+"正在挑衣服……");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t+"..."+"正在试衣服……");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t+"..."+"正在买衣服……");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("买完辣");
}
}


运行时,发现两个人在一起试衣服。比较尴尬,现实中不会允许这种情况出现,所以为了避免一起试衣服。所以将run方法加了synchronized关键字。

但是运行过程中,又出现了“必须分别挑衣服和分别买衣服”的状况,而在现实生活中,两个人一起挑衣服->试衣服->买衣服的过程,真正需要分开的只有“试衣服”的阶段。所以需要只给“试衣服”实现同步。

方法:使用synchronized代码块
synchronized(this){
System.out.println(t+"..."+"正在试衣服……");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

代码块后面括号中需要传入一个对象,表示“锁”,也就是说,想要访问此代码块的线程必须要拿到相应的实例。否则阻塞。

进一步理解函数中的synchronized声明:其实就是给函数加了调用此函数的对象的Class实例。

所以:

1.如果是synchronized字段修饰的静态方法,不管有多少个实例对象,都是同步的(因为锁只有一个,为虚拟机加载此类时产生的Class实例)。

2.同一个实例中多个以synchronized修饰的方法也是同步的(同样也是因为锁只有一个,为该对象的实例)。

StringBuffer和StringBuilder的区别:StringBuffer是线程安全的,StringBuilder不是。所以在动用多个线程调用一个时,应选用StringBuffer,防止乱码产生(几个线程轮流操作导致内容错乱)。而StringBuilder效率更高。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: