当前位置:   article > 正文

Java多线程(一)--之线程范围内共享变量的概念与作用_多线程为什么需要共享变量

多线程为什么需要共享变量

最近在学习多线程,通过看了一些视频教程和博客后,我觉得对自己的编程学习又有了进一步的认识,在此,以这篇博客记录下学习的知识,分享给需要的朋友。

一、首先试着创建两个线程:

创建一个测试类:ThreadScopeShareVariable

  1. public class ThreadScopeShareVariable {
  2. private static int datas = 0;
  3. public static void main(String[] args) {
  4. for(int i=0;i<2;i++){
  5. new Thread(new Runnable() {
  6. @Override
  7. public void run() {
  8. datas = new Random().nextInt();
  9. System.out.println("put variable is :"+datas+" to Thread:"+Thread.currentThread().getName());
  10. new A().get();
  11. new B().get();
  12. }
  13. }).start();
  14. }
  15. }
  16. static class A{
  17. public void get(){
  18. System.out.println("A get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  19. }
  20. }
  21. static class B{
  22. public void get(){
  23. System.out.println("B get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  24. }
  25. }
  26. }

嗯,上面的是测试code,运行输出如下

看了上面的结果,按照预想应该是    Thread-1产生的变量,运行到A方法后,线程的名字和它携带的variable应该是一致的才对,但是实际运行起来确不是这样的,这时候呢就和我们的需求不一样了。

那怎么样才能达到我们的需求呢?

这里我们可以借助一个Map集合来实现,将我们的变量数据放进Map里面,Map<Thread,Integer>,然后按当前线程来获取它携带的数据,直接撸代码:

创建一个ThreadScopeShareMapDemo类

  1. public class ThreadScopeShareMapDemo {
  2. private static Map<Thread,Integer> maps = new HashMap<Thread,Integer>();
  3. public static void main(String[] args) {
  4. for(int i=0;i<2;i++){
  5. new Thread(new Runnable() {
  6. @Override
  7. public void run() {
  8. int datas = new Random().nextInt();
  9. System.out.println("put variable is :"+datas+" to Thread:"+Thread.currentThread().getName());
  10. maps.put(Thread.currentThread(), datas);
  11. new A().get();
  12. new B().get();
  13. }
  14. }).start();
  15. }
  16. }
  17. static class A{
  18. public void get(){
  19. int datas = maps.get(Thread.currentThread());
  20. System.out.println("A get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  21. }
  22. }
  23. static class B{
  24. public void get(){
  25. int datas = maps.get(Thread.currentThread());
  26. System.out.println("B get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  27. }
  28. }
  29. }

嗯,看了上面的代码,真的很简单,哈哈慢慢来嘛。。。。。其实相对于上一块也没改动多少。。我想追求的是对于一个过程的享受,这样你会获得更多的信息。。。

下面我们再来看看它运行的结果:

看着就是我想要的结果,不管哪个线程怎么样运行,它携带的数据是不会错误的。嗯。。。。。

对于上面的方法呢,其实java多线程里面早就提供了这样一个类,相对于上面的更加简洁,其实里面的实现方式也是差不多和上面的Map集合一样。这里我就直接撸代码吧

  1. public class ThreadScopeShareLocalDemo {
  2. /*private static Map<Thread,Integer> maps = new HashMap<Thread,Integer>();*/
  3. private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
  4. public static void main(String[] args) {
  5. for(int i=0;i<2;i++){
  6. new Thread(new Runnable() {
  7. @Override
  8. public void run() {
  9. int datas = new Random().nextInt();
  10. System.out.println("put variable is :"+datas+" to Thread:"+Thread.currentThread().getName());
  11. threadLocal.set(datas);
  12. new A().get();
  13. new B().get();
  14. }
  15. }).start();
  16. }
  17. }
  18. static class A{
  19. public void get(){
  20. int datas = threadLocal.get();
  21. System.out.println("A get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  22. }
  23. }
  24. static class B{
  25. public void get(){
  26. int datas = threadLocal.get();
  27. System.out.println("B get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  28. }
  29. }
  30. }

就不必多说了,看看结果

嗯,结果达到了我们的需求,代码也更加简单。。。

上面实现了这么多,我也看了一些博客和视频,最后呢我们来实现,线程范围内共享N个数据呢?这个这么实现,这个时候我们可以用一个实体类来封装这N个数据,在这里呢,通过不断学习,学习到了代码的规范性,和优雅性,下面让我们来看看这个优雅是怎么的优雅?用了饥汉式的模式实现:

  1. public class ThreadScopeShareLocalInstanceDemo {
  2. public static void main(String[] args) {
  3. for(int i=0;i<2;i++){
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. int datas = new Random().nextInt();
  8. System.out.println("put variable is :"+datas+" to Thread:"+Thread.currentThread().getName());
  9. SharResource sharResource = SharResource.getInstance();
  10. sharResource.setName(Thread.currentThread().getName());
  11. sharResource.setData(datas);
  12. new A().get();
  13. new B().get();
  14. }
  15. }).start();
  16. }
  17. }
  18. static class A{
  19. public void get(){
  20. SharResource sharResource = SharResource.getInstance();
  21. int datas = sharResource.getData();
  22. System.out.println("A get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  23. }
  24. }
  25. static class B{
  26. public void get(){
  27. SharResource sharResource = SharResource.getInstance();
  28. int datas = sharResource.getData();
  29. System.out.println("B get variable is :"+datas+",from Thread:"+Thread.currentThread().getName());
  30. }
  31. }
  32. }
  33. //实现N变量共享
  34. class SharResource{
  35. private String name;
  36. private int data;
  37. //这里用私有初始化,是为了不让外界随便使用它,而是让外界按照我们给定的接口去创建。
  38. private SharResource(){}
  39. private static ThreadLocal<SharResource> threadLocal = new ThreadLocal<SharResource>();
  40. //运用饥汉式的模式创建实体类
  41. public static SharResource getInstance(){
  42. SharResource instance = threadLocal.get();
  43. if(instance == null){
  44. instance = new SharResource();
  45. threadLocal.set(instance);
  46. }
  47. return instance;
  48. }
  49. public String getName() {
  50. return name;
  51. }
  52. public void setName(String name) {
  53. this.name = name;
  54. }
  55. public int getData() {
  56. return data;
  57. }
  58. public void setData(int data) {
  59. this.data = data;
  60. }
  61. }

我们来看一下输出的结果:

这个达到了我们的期望,写了这么多,这个就是相当于上面两个的概括吧,怎么样,这种写法看起来是否觉得舒服点(这里我直接使用外部类和内部类是为了看的方便些,但在实际开发中不要这样写。。。)。听说这种实现的模式跟strus2有点类似

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/220835
推荐阅读
相关标签
  

闽ICP备14008679号