今天被阿里面跪了,其中有一个问题我目前还没有想到答案,他们提出的问题是,不要用锁,不要用sychronized块或者方法,也不要直接使用jdk提供的线程安全的数据结构,需要自己实现一个类来保证多个线程同时读写这个类中的共享数据是线程安全的,怎么破?
------解决思路----------------------
我的思路:
在这个类中维护一个队列,用来记录要访问共享数据的线程。每次只能由队列头部所表示的线程访问这些数据,一旦这个线程访问完毕,就出队。
这是看Python官方文档得到的启示。
------解决思路----------------------
public class Counter {
public volatile static int count = 0;
public static void inc() {
//这里延迟1毫秒,使得结果明显
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
count++;
}
public static void main(String[] args) {
//同时启动1000个线程,去进行i++计算,看看实际结果
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
// @Override
public void run() {
Counter.inc();
}
}).start();
}
//这里每次运行的值都有可能不同,可能为1000
System.out.println("运行结果:Counter.count=" + Counter.count);
}
}
------解决思路----------------------
class ThreadSafe{
private static int toSecond = 5*1000; //超时毫秒数
private boolean flag = false;
private int source = 1;
public int printSource(){
return source;
}
public boolean incSource(){
if (!canAccess()){
return false;
}
flag = true;
source++;
flag = false;
return true;
}
public boolean decSource(){
if (!canAccess()){
return false;
}
flag = true;
source--;
flag = false;
return true;
}
/**
* 判断能不能访问,不能访问说明在修改,要等待一下
*/
private boolean canAccess(){
int time=0;
while (flag){
try{
Thread.sleep(2);
}catch(Exception ex){
//不考虑那么多,不做处理
}
time+=100;
//这里也不考虑那么多,认为循环一次就100毫秒
if (time>toSecond){
return false;
}
}
return true;
}
}
根据各位大牛的意见写个例子让大家喷喷。
------解决思路----------------------
jvm对final域会做特殊化处理,final域可以保证可见性,由于final域是不可变的,故而无需担心多线程并发导致的数据不一致问题,不过我还得补充一点,就是当final域为对象引用时,final域引用的对象是可变的时,仍然是非线程安全的,
我说的还是有点纠结,说白了就是把这个类设计为不可变类。不可变类绝对是线程安全的。