如何解决线程不安全问题呢?

线程安全问题存在,必然会引起很多问题。那么本节就来讲讲,如何解决线程安全问题呢?

1、synchronized

synchronized关键字,就是java用来控制线程同步的,比如上节的最后举例中,在代码中加入共享变量后,使用多线程调用时,会产生count数据产生偏差问题。

 

此关键字,一般是加在方法上的如:

public static int count =0;

    public static  void  main(String[] args){
        for (int i = 0; i <3 ; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(getcountNum(30));
                    System.out.println("count为:"+count);
                   try{
                       Thread.sleep(1);
                   }catch (Exception e){
                       e.printStackTrace();
                   }
                }
            }).start();
        }
    }

    public static synchronized  int getcountNum(int j){
        int i =1;
        count++;
        j=j+3;
        return j;
    }

运行结果为:

如何解决线程不安全问题呢?_第1张图片

此方法就变成了一个线程安全的方法了。

首先synchronized锁的是括号里的对象,而不是代码,其次,对于非静态的synchronized方法,锁的是对象本身也就是this。

当synchronized锁住一个对象之后,别的线程如果想要获取锁对象,那么就必须等这个线程执行完释放锁对象之后才可以,否则一直处于等待状态。

虽然加synchronized关键字,可以让我们的线程变得安全,但是我们在用的时候,也要注意缩小synchronized的使用范围,如果随意使用时很影响程序的性能,别的对象想拿到锁,结果你没用锁还一直把锁占用,这样就有点浪费资源。

也就是说:1.非static方法,同步锁是this。2.static方法,使用当前方法所在类的字节码对象(Apple.class)是同步锁

2、lock

       先来说说它跟synchronized有什么区别吧,Lock是在Java1.6被引入进来的,Lock的引入让锁有了可操作性,什么意思?就是我们在需要的时候去手动的获取锁和释放锁,甚至我们还可以中断获取以及超时获取的同步特性,但是从使用上说Lock明显没有synchronized使用起来方便快捷。我们先来看下一般是如何使用的:

 public static  void  main(String[] args){

        for (int i = 0; i <3 ; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    getcountNum(Thread.currentThread(),30);
                   try{
                       Thread.sleep(1);
                   }catch (Exception e){
                       e.printStackTrace();
                   }
                }
            }).start();
        }
    }
  private static   Lock lock = new ReentrantLock();
    public static  int getcountNum(Thread a,int j){
        lock.lock();
         int i =1;
         count++;
        System.out.println("当前是线程:"+a.getName()+",count="+count);
         j=j+3;
         lock.unlock();

        return j;
    }

上次分享线程不安全的文章中,得到的count全是3,加上锁后得到结果是:

如何解决线程不安全问题呢?_第2张图片

 

 

你可能感兴趣的:(多线程,java,多线程)