我认为并发大体上分为两种情况
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是把变量加入到线程内变量中,所以相当于每个线程访问自己的变量,和别的线程互不影响。相当于变量的副本。
-------如有错误指正,不胜感激