1 2 3 4

java 线程八锁

锁一

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       new Thread(test::methon1,"线程a").start();
       new Thread(test::method2,"线程b").start();
   }
}

class LockTest{
   public  synchronized void methon1(){
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

在成员函数上添加synchronized关键字,相当于锁住了this对象、因此上述代码锁住的是同一对象test、具有互斥性。当线程a获取到锁时、线程b进入阻塞状态、等待线程a执行完后、释放对象锁、线程b才能获取对象锁、执行语句的打印。如果是线程b优先获取到test的对象锁、也是一样、线程a进入阻塞状态、等待线程b执行结束、释放对象锁、线程a才能执行


锁二

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       new Thread(test::methon1,"线程a").start();
       new Thread(test::method2,"线程b").start();
   }
}

class LockTest{
   public  synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

与锁一类似、锁住的也是同一对象test、具有互斥性、Thread.sleep()方法不会释放锁、所以运行结果为:如果线程a优先获取到了对象锁、线程b进入阻塞状态、等待获取到对象锁的线程释放锁。线程a执行时首先睡眠1s、睡眠中不会释放对象锁、线程b还是处于阻塞状态。直到线程a执行完毕、释放锁。线程b才能运行。如果线程b优先获取到了对象锁、那么线程a进入阻塞状态、等待线程b执行完毕释放对象锁、线程a才能执行


锁三

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       new Thread(test::methon1,"线程a").start();
       new Thread(test::method2,"线程b").start();
       new Thread(test::method3,"线程c").start();
   }
}

class LockTest{
   public  synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }

   public void method3(){
    try {
           //在method3方法种添加休眠语句、更能直观看到、执行此方法和其他同步方法交替运行的效果
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 100; i < 150; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

method1和methond2成员方法上均添加有Synchronized关键字、因此锁住的是this对象、具有互斥性,但method3没有添加synchronized关键字、因此不会受到锁的影响。程序运行结果为:线程c优先获取到cpu资源、打印100-149、然后可能线程a获取cpu资源、等待1s、打印1-49,左后线程b执行打印50-99。又或许线程c执行完、线程b先获取到锁打印50-99、接着线程a等待1s打印0-49。也可能是线程b优先获取cpu资源、获取到test的独享锁打印40-99、然后线程c执行、线程c执行完后、线程等待1s打印0-49。总而言之、线程c可以和线程a或线程B交替执行、但线程a和线程b会有一个线程阻塞等待test对象锁、肯定不会交替执行、只会等待一个线程执行借结束后释放锁、另一个线程才能执行


锁四

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       LockTest test1 = new LockTest();
       new Thread(test::methon1,"线程a").start();
       new Thread(test1::method2,"线程b").start();

   }
}

class LockTest{
   public  synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

synchronized关键字添加到成员函数上、锁住的是this对象,但是由于程序种有两个LockTest对象test和test1,因此锁住的不是同一对象、不具有互斥性、线程a和线程b会交替运行、不会造成线程阻塞、主要看cpu的调度


锁五

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       LockTest test1 = new LockTest();
       new Thread(LockTest::methon1,"线程a").start();
       new Thread(test1::method2,"线程b").start();

   }
}

class LockTest{
   public  static synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

synchronized关键字放到静态方法上、锁住的是类对象、放到成员方法上、锁住的是this对象。因此上述程序锁住的是不同的对象、不具有互斥性、线程a和线程b不会有等待对象锁的情况而造成线程的阻塞、两个线程交替运行


锁六

public class ThreadLockDemo {
   public static void main(String[] args) {
       new Thread(LockTest::methon1,"线程a").start();
       new Thread(LockTest::method2,"线程b").start();

   }
}

class LockTest{
   public  static synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public static synchronized  void method2(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

synchronized放到静态方法上,是对类对象加锁、而java种类对象在内存中只会存在一份。因此锁住的是同一个对象、线程a、线程b谁先获取到LockTest类对象的锁、谁先执行、执行完后释放锁、另外一个线程才能执行


锁七

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       new Thread(LockTest::methon1,"线程a").start();
       new Thread(test::method2,"线程b").start();

   }
}

class LockTest{
   public  static synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public synchronized  void method2(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

method1锁住的类对象、而method2方法锁住的this对象、两个线程不是同一锁、所以不具有互斥性。线程a和线程b不会造成阻塞、两个线程交替运行


锁八

public class ThreadLockDemo {
   public static void main(String[] args) {
       LockTest test = new LockTest();
       LockTest test1 = new LockTest();
       new Thread(()->{test.method2();},"线程a").start();
       new Thread(()->{test1.methon1();},"线程b").start();

   }
}

class LockTest{
   public  static synchronized void methon1(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 0; i < 50; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
   public static  synchronized     void method2(){
       try {
           Thread.sleep(1000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       for (int i = 50; i < 100; i++) {
           System.out.println(Thread.currentThread().getName()+" i="+i);
       }
   }
}

以上代码method1和method2都是静态方法、因此锁住的都是类对象、虽然主线程创建test、test1两个对象、但在内存中类对象始终只有一个。因此锁住的是同一对象:程序运行结果:两个争夺LockTest类对象锁、那个线程获取到锁可以执行、执行完后、释放对象锁、另一线程才能继续执行

posted @ 2022-04-27 14:26  startscorpio  阅读(283)  评论(0编辑  收藏  举报