线程同步

1,为什么要有线程同步
比如说你有的银行账户有1000块钱,你有一个存折还有一张ATM卡,那么你是不是就可以在你朋友的帮助下同时登录你的帐号,然后没人去到1000呢?结果是显而易见的,这是不可能的。所以为了避免多个线程访问一个数据对象时,对数据造成破坏,我们使用线程同步。
在这段代码中多个线程访问了一个数据对象,造成了数据的破坏,
 

public class Test {
  private int x = 100;
  
  public int getX() {
   return x;
  }
 
  public int fix(int y) {
   x = x - y;
   return x;
  }

 }



  

public class MyRunnable implements Runnable {
  private Test test = new Test();

  public static void main(String[] args) {
   MyRunnable mr = new MyRunnable();
   Thread ta = new Thread(mr, "A--->");
   Thread tb = new Thread(mr, "B--->");
   ta.start();
   tb.start();
  }

  @Override
  public void run() {
   for (int i = 0; i < 3; i++) {
    this.fix(30);
    try {
     Thread.sleep(1);
    } catch (Exception e) {
     e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName() + "当前test对象的x值="
     + test.getX());
   }

  }

  public int fix(int y) {
   return test.fix(y);
  }

 }

  打印结果:
 A--->当前test对象的x值=40
 B--->当前test对象的x值=40
 B--->当前test对象的x值=-20
 A--->当前test对象的x值=-50
 B--->当前test对象的x值=-80
 A--->当前test对象的x值=-80

这样的结果是很不合理的,为了保持其合理性,给Test访问加上限制,每次只能允许一个线程对其进行访问。

 

1)用synchronized对方法进行修饰,
 在fix方法前加上chynchronized,锁定该方法

2)对那先操作共享资源的关键代码进行加锁
 

public int fix(int y) {
  synchronized(this){
   x = x - y;
   return x;
  }
 }

  

3)用Lock加锁
 class A {
        //创建锁对象
        private final Lock lock = new ReentrantLock();
        ......
        //保证线程安全方法
        public void method() {
            //上锁
            lock.lock();
            try {
                //需要同步的代码
            } catch() {
           
            } finally {
                lock.unlock();//解锁
            }
        }
    }

 

你可能感兴趣的:(基础,线程同步)