并发状况下,下面两个类是否线程安全?java
public class Counter {
private int count;
public void increase() {
count = count + 1;
}
public int getCount() {
return count;
}
}
public class Basket {
//Vector是线程安全的集合
Vector<Fruit> v = new Vector<Fruit>();
public void put(Fruit fruit) {
v.add(fruit);
}
public Fruit tackOut() throws Exception {
if (v.size() > 0) {
return v.remove(0);
} else {
throw new Exception("There is no fruit in basket.");
}
}
}
复制代码
答案:以上两个类在并发状况下均不能保证线程安全。编程
线程安全:当多个线程访问某个类时,这类始终都能表现出正确的行为,那么这个类是线程安全的。缓存
原子性:一个或者多个操做在CPU执行的过程当中不被中断的特性称为原子性。安全
而以上两个类不能保证操做原子性致使不能表现正确的行为,所以都不是线程安全的。多线程
1.在类Counter中,如下代码实际执行了三个指令:并发
count = count + 1;
复制代码
在多线程并发状况下因为线程切换会致使计算结果不正确。post
注:图片参考Java并发编程实战优化
2.在类中的以下代码不是原子的,可能会致使抛出空指针异常和预期不符:ui
if (v.size() > 0) {
return v.remove(0);
}
复制代码
原子性能够经过加锁来解决,修正以下:spa
public class Counter {
private int count;
public synchronized void increase() {
count = count + 1;
}
/** 原子操做可不加同步关键字 */
public int getCount() {
return count;
}
}
public class Basket {
Vector<Fruit> v = new Vector<Fruit>();
/** 原子操做可不加同步关键字 */
public void put(Fruit fruit) {
v.add(fruit);
}
/** 加上synchronized关键字 */
public synchronized Fruit tackOut() throws Exception {
if (v.size() > 0) {
return v.remove(0);
} else {
throw new Exception("There is no fruit in basket.");
}
}
}
复制代码
end.
相关阅读:
Java并发编程(一)知识地图
Java并发编程(三)可见性
Java并发编程(四)有序性
Java并发编程(五)建立线程方式概览
Java并发编程入门(六)synchronized用法
Java并发编程入门(七)轻松理解wait和notify以及使用场景
Java并发编程入门(八)线程生命周期
Java并发编程入门(九)死锁和死锁定位
Java并发编程入门(十)锁优化
Java并发编程入门(十一)限流场景和Spring限流器实现
Java并发编程入门(十二)生产者和消费者模式-代码模板
Java并发编程入门(十三)读写锁和缓存模板
Java并发编程入门(十四)CountDownLatch应用场景
Java并发编程入门(十五)CyclicBarrier应用场景
Java并发编程入门(十六)秒懂线程池差异
Java并发编程入门(十七)一图掌握线程经常使用类和接口
Java并发编程入门(十八)再论线程安全
Java极客站点: javageektour.com/