欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程请求给静态变量加锁的

程序员文章站 2022-03-02 08:11:29
...

1、写在前面
今天在写一个当每次请求过来定义的一个静态变量累加的时候遇到很多坑,发现自己对多线程和锁的理解和使用一窍不通,对Java一些设计模式真的是一知半解!!心生惭愧,感谢部门大佬耐心的讲解和帮助!让我也明白写程序不能只是使用,还要明白更要弄懂每写一行代码的意义! 在csdn已经写了很久了,这是我第50篇文章,在这里碎碎念一下,同时也希望看到自己的成长,加油,陌生人! 加油,自己!

2、问题解决及描述
A、在给静态变量累加的时候专门添加一个方法,用synchronized 来修饰加锁,保证每次多线程请求的时候拿到的都是累加的! 为什么可以用synchronized ,因为它有一个特点:互斥性,就是:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性!

   public static BigInteger number= new BigInteger("0");

    public static synchronized BigInteger GetNumber() {
    	//这里加休眠是为了 模拟 当很多个请求一起来的时候会不会重复拿到number变量
    	Thread.sleep(3000);
        number= number.add(new BigInteger(1"));
        return number;
    }

   @Test
    public void contextLoads() {

        for (int i = 0; i < 50; i++) {
            Test mythread = new Test ();
            Thread a = new Thread(mythread, "A" + i);
            a.start();
        }
		
		//在springboot 中test中为了看控制台加上的
        while (true) {
            try {
                Thread.sleep(600000);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }

    }
  public class test extends Thread {
  @Override
        public void run() {
            super.run();
            // System.out.println("MyThread");
            String thredName = test.currentThread().getName();
            System.out.println("线程:" + thredName + "进来了");
            System.out.println(GetNumber());
            System.out.println("线程:" + thredName + "出去了");           
        }

}


输出结果: (也可以不用来打印一下看看)
线程:A41进来了
线程:A42进来了
线程:A43进来了
线程:A44进来了
线程:A45进来了
线程:A46进来了
线程:A47进来了
线程:A48进来了
线程:A49进来了
0
线程:A0出去了
1
线程:A49出去了
2
线程:A48出去了
3
线程:A47出去了
4
线程:A46出去了
5
线程:A45出去了
6

B、使用synchronized给代码块修饰(如上面代码)

public static BigInteger GetNumber2() {
        try {
            Thread.sleep(100L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        number= number.add(new BigInteger("1"));
        return number;
    }
 
 @Test
    public void contextLoads() {

        for (int i = 0; i < 10; i++) {
            test mythread = new test();
            Thread a = new Thread(mythread, "A" + i);
            a.start();
        }

        while (true) {
            try {
                Thread.sleep(600000);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }

public class test extends Thread {
        @Override
        public void run() {
            super.run();
           	//修饰整个类
            synchronized (test.class) {
  
                System.out.println(GetNumber2());
            }
            System.out.println("线程:" + thredName + "出去了");
        }

    }


运行结果:
线程:A0进来了
线程:A1进来了
线程:A2进来了
线程:A3进来了
线程:A4进来了
线程:A5进来了
线程:A6进来了
线程:A7进来了
线程:A8进来了
线程:A9进来了
0
线程:A0出去了
1
线程:A9出去了
2
线程:A8出去了
3
线程:A7出去了
4
线程:A6出去了
5
线程:A5出去了
6
线程:A4出去了
7
线程:A3出去了
8
线程:A2出去了
9
线程:A1出去了

3、写在最后
路漫漫其修远兮,吾将上下而求索!