Lock实现线程通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33248299/article/details/78778263

Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须要同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是变成代码中!

读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的低吗只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人再写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!

  • Lock在java,util.concurrent.locks包下

  • 开两个线程打印名字,用synchronized实现效果如下

public class LockTest {
    public static void main(String[] args) {
        new LockTest().init();

}

  public void init() {
      final Output output = new Output();

      new Thread(new Runnable() {

        @Override
        public void run() {
            while(true) {
             output.getName("zhouyuan");
            }

        }
    }).start();

      new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
                 output.getName("muchen");
                }

            }
        }).start();



  }
 static class Output{
       public void getName(String name) {
                  synchronized (Output.class) {
                  for(int i=0;i<name.length();i++) {
                      System.out.print(name.charAt(i));
                  }
                  System.out.println();
                  }
              }
  }
}
  • 把以上改成Lock实现
public class LockTest {
    public static void main(String[] args) {
        new LockTest().init();

}

  public void init() {
      final Output output = new Output();

      new Thread(new Runnable() {

        @Override
        public void run() {
            while(true) {
             output.getName("zhouyuan");
            }

        }
    }).start();

      new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
                 output.getName("muchen");
                }

            }
        }).start();



  }
 static class Output{
      Lock lock = new ReentrantLock();
      public void getName(String name) {
          try {
          for(int i=0;i<name.length();i++) {
              System.out.print(name.charAt(i));
          }
          System.out.println();

      }
  }
}
  • 虽然上面的代码没有什么大的问题,不过还是存在一个问题,如果在for循环内抛出了异常,那么这个getName方法就直接跳出了,就不会运行解锁,所以我们最好加上finally,如下
public class LockTest {
    public static void main(String[] args) {
        new LockTest().init();

}

  public void init() {
      final Output output = new Output();

      new Thread(new Runnable() {

        @Override
        public void run() {
            while(true) {
             output.getName("zhouyuan");
            }

        }
    }).start();

      new Thread(new Runnable() {

            @Override
            public void run() {
                while(true) {
                 output.getName("muchen");
                }

            }
        }).start();



  }
 static class Output{
      Lock lock = new ReentrantLock();
      public void getName(String name) {
         lock.lock();
          try {
          for(int i=0;i<name.length();i++) {
              System.out.print(name.charAt(i));
          }
          System.out.println();
          }finally {//如果for内抛异常,不加这个这个方法就直接跳出了
             lock.unlock();
        }

      }
  }
}

猜你喜欢

转载自blog.csdn.net/qq_33248299/article/details/78778263