我认为并发大体上分为两种情况
1,多个线程或者进程访问公共资源,比如12306
2,多个线程访问同一个实例变量,比如tomcat 多个请求的线程访问同一个单例bean,如果bean是有状态的,就可能出现并发问题
对于第一种情况,在同一个jvm下可以通过java 同步关键字synchronized解决。但是在分布式的情况下,则要用其他的方式解决,比如数据库乐观锁,zookeeper.
拿买票来举例,比如id 111还有10张票,现在同是有很多请求要要更新数据
id | num |
111 | 10 |
伪代码类似于:
int num=10;//select * from db d
while(true){
int result=updateDBbyNum(num);//update db d set d.num=d.num-1 where d.num=10
if(result==1){
break;
}else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
}
对于第二种情况,如果bean实在没办法改成无状态的,可以通过threadlocal解决
public class ThreadLocalTest { //创建一个Integer型的线程本地变量
public static final ThreadLocal<Integer> local = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[5];
for (int j = 0; j < 5; j++) {
threads[j] = new Thread(new Runnable() {
@Override
public void run() {
//获取当前线程的本地变量,然后累加5次
int num = local.get();
for (int i = 0; i < 5; i++) {
num++;
}
//重新设置累加后的本地变量
local.set(num);
System.out.println(Thread.currentThread().getName() + " : "+ local.get()); }
}, "Thread-" + j);
} for (Thread thread : threads) {
thread.start();
}
}
}
threalocal是把变量加入到线程内变量中,所以相当于每个线程访问自己的变量,和别的线程互不影响。相当于变量的副本。
-------如有错误指正,不胜感激