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、具有互斥性、程序运行结果为先打印0-49 在打印50-99 或者先打印50-99 然后打印0-49
锁二
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优先抢到cpu资源、等待1s后打印0-50、然后线程b执行。或者线程b优先抢到cpu资源、打印50-99、然后线程a执行、等待1s打印0-49
锁三
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) { LockTest test = new LockTest(); LockTest test1 = new LockTest(); 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类对象锁、那个线程获取到锁可以执行、执行完后、释放对象锁、另一线程才能继续执行
标签:八锁,java,Thread,LockTest,void,线程,new,public 来源: https://www.cnblogs.com/startscorpio/p/16198771.html