zpitblog

导航

 

我认为并发大体上分为两种情况

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是把变量加入到线程内变量中,所以相当于每个线程访问自己的变量,和别的线程互不影响。相当于变量的副本。

-------如有错误指正,不胜感激

 

posted on 2016-01-02 13:30  zpitblog  阅读(359)  评论(0编辑  收藏  举报