A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HelloWorld_2013 中级黑马   /  2013-4-13 13:23  /  1360 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HelloWorld_2013 于 2013-4-14 15:55 编辑

线程安全问题。。

6 个回复

倒序浏览
java多线程安全问题的解除步骤

         1.明确多线程执行代码。(run方法中的代码都是多线程执行代码,如果在run方法体中调用了其他方法,那么其他方法所包含的代码也是多线程执行代码)

         2.明确多线程共享数据。(创建多线程对象时传递给Thread(Object o)构造函数的对象,是共享数据(注:对象中的属性、以及包含的其他对象都是共享数据),当对象中包含其他的对象时,那么其他的对象中的所有数据也都是共享数据。

         3.明确多线程执行代码中操作了共享数据的代码,将操作了共享数据的代码放入synchronized(Object o )方法体中,这样线程安全问题就解决。(注:还可使用另一种行式的代码来处理操作了共享数据的代码。它们产生的作用是一样的,只是代码的形式不同)

              另一种行式:假如add(int n)方法封装了操作共享数据的代码,只需将synchronized作为修饰符,修饰add(int n)方法即可。synchronized修饰符位于访问权限修饰符之后,返回值类型之前。注:常用技巧,定义一个synchronized修饰的函数,将某处操作了共享数据的代码移到函数中,再在代码的原始位置调用该函数。

               如: public synchronized void  add(int n){


                             //将共享数据的值加上n


                                sum+=n;

                             //将共享数据的值输出


                       System.out.println("sum="+sum);


                  }         

   示例代码:

          class Bank{

             //共享数据对象中包含了Bank对象,所Bank对象中的sum也是共享数据


              private int sum;

            Object obj = new Object();


             public void  add(int n){

                //将操作了共享数据sum的代码放入synchronized(Object o )方法体中


                synchronized(obj ){

                 //将共享数据的值加上n


                 sum+=n;

                //将共享数据的值输出


                 System.out.println("sum="+sum);


                  }              


            }      


}

          //定义共享数据对象的类。


          class Cus implements Runnable{

                //在共享数据对象的类创建一个Bank,所以Bank也是一个共享数据,Bank对象中所包含的数据也都是共享数据。


                 private Bank b = new Bank();

                 public  void run(){

                          //run方法体中的代码都是多线程执行的代码。


                          for(int x=0; x<3; x++){

                          //run方法体中调用了add(int n)方法,add(int n)方法中的代码也是多线程执行的代码。


                                  b.add(100);


                          }


                  }


}

class BankDemo{

               public static void main(){

                      //创建Cus对象,该对象为共享数据


                      Cus c = new Cus();

                      // 创建两个线程对象,并共享数据传给两个线程对象。


                       Thread t1= new Thread(c);

                        Thread t2= new Thread(c);

                        //开启两个线程


                         t1.start();

                         t1.start();


               }


}

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
同步线程(解决线程安全)

线程安全问题产生的原因:
               
多个线程通过多条语句去操作共享数据

怎样解决线程的安全问题
                       
        当某一个线程在操作数据时,它没有操作完,其它的线程是不允许操作的。
        只有当这个线程执行完成后,我们才允许其它线程操作。我们管这种机制叫锁的机制.

线程同步的问题
                       
        两种解决方式
                               
        1.使用synchronized 块

                synchronized(对象){
                        多条语句操作的数据
                }

                锁的对象可以是任意对象

        2.使用synchronized 方法

                使用同步代码块解决安全问题注意事项
                         
                         所有的线程在操作时,要保证线程是安全的,
                         必须保证所使用的锁是同一个.

                       
                同步方法

                其时就是使用synchronized去修饰一个方法.

                        同步代码块与同步方法的原理是一样的,
                        区别在于它们所控制的范围不一样。
                        同步方法它是将整个方法都锁定。
                        线程没有执行完这个方法,其它线程是不能执行的。

                        而同步代码块我们可以控制只方法中的某一部分去锁。

                        在实际操作中建议使用同步代码块。


                同步的弊端:
                        多线程的优点:提高效率
                        使用同步后就使的多线程程序的效率降低.
                       
                将同步方法详细分析

                        同步方法它其时也是使用同步代码块实现的。
                        那么同步方法它所使用的锁是什么?


                        非静态的同步方法所使用的锁对象就是this
                        静态的同步方法所使用的锁对象不是this,
                        当前静态同步方法所使用的锁对象就是线程类的.class文件对象.



                        java中的所有的类都有一个静态的属性叫做.class
                        它的作用是得到当前类的字节码对象.

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
有2种解决方法。第一,是采用原子变量,毕竟线程安全问题最根本上是由于全局变量和静态变量引起的,只要保证了对于变量的写操作要么全写要么不写,就可以解决线程安全,定义变量用sig_atomic_t和volatile。第二,就是实现线程间同步啦,用互斥索,信号量。让线程有序的访问变量就可以啦
回复 使用道具 举报
1,同步代码块。
2,同步函数。掌握这2知识点,可以解决线程安全问题
回复 使用道具 举报
解决多线程的安全问题的办法是:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中其他线程不可以参与执行。
java对多线程安全问题通过同步的方式进行解决:
同步代码块:synchronized(对象)
                   {
                         线程操作的共享数据;
                  }
同步函数:通过将线程操作的共享数据封装到一个方法中,用synchronized来修饰该方法。
同步函数效率要比同步代码块低,所以建议使用同步代码块。

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
黄玉昆 黑马帝 2013-4-14 14:08:04
7#
如果问题未解决,请继续追问,如果没有问题了,请将帖子分类 改为“已解决”,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马