java线程同步中使用自增操作时的注意

来源:互联网 发布:2016年网络搜索话题 编辑:程序博客网 时间:2024/06/08 16:40

在这里讲一个很多新手可能会出错的地方:就是在线程中进行加法操作,这里说的是 在多线程中操作同一份内存中的数据,然后对其进行加法运算
不要觉得不就是加法嘛,会有什么问题。要是这样我还说个球啊!!不过,讲道理我在大学里学习数据库的理论知识的时候也没记得说加法也会存在线程同步的问题。废话不多说先来看一个简单的例子

class MyThread extends Thread{  public void run(){    ++x;  }}

其中的x是全局静态变量,然后启动多个MyThread。不要被我忽悠了,上面的例子本身是没有什么问题的,但是如果你觉得完全可以这样使用那你就等着找问题吧!!!不信的话可以试试下面这个例子

class MyThread extends Thread{    int i=0;  public void run(){  while(i<400)    ++x;    i++;  }  if(x==1600){  //打印信息,提示x到了1600  }}

上面的x依旧是全局静态变量,初始值为0,i是局部变量,然后启动4个线程运行起来,单单用想的话最后会打印出x到1600的提示信息,但是当你真的运行了之后发现,x基本上都不会到1600,然而你打印i的值看下却可以看到四个线程的i都已经等于400,那么我们的问题就来了,为什么i到了400而x却没有到1600。===================================================================================================================================
不用想了,我也不知道原理,所以也没办法告诉你,如果有兴趣的话可以去看下java的编译原理、java虚拟机什么的应该能找到答案,你也不用再尝试什么x++或者x=x+1什么的,我可以告诉你这跟这些没关系。所以这里我只是善意的提醒一下要注意自增在java中也是线程不安全的,如果非要用的话可以使用synchronized关键字或者AtomicInteger(一个提供原子操作的Integer的类),不知道怎么用的自行查阅。
最后还要注意上面说的是继承Thread的线程,还有实现Runnable接口的线程,而Runnable中要注意的一点是其中的数据都是线程共享的,所以像上面例子中的i,在实现Runnable接口的线程中也不能直接随意使用。

0 0
原创粉丝点击