源无极

导航

 

一、使用ReentrantLock类

           除了Synchronized达到现场之间同步互斥外,还可以使用ReentrantLock类

也能达到同样的效果,其在扩展功能上也更加强大,比如有嗅探锁定,

多路分支通知等功能,使用上也比Synchronized 更灵活。

(一)、ReentrantLock类 使用

package com.it.po.thread11;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService {
private Lock lock =new ReentrantLock();
public void testMethod(){
    lock.lock();//加锁
    for(int i=0;i<5;i++){
        String name = Thread.currentThread().getName();
        System.out.println("线程 "+name+" "+(i+1));
    }
    lock.unlock();//释放锁
}

}

 

package com.it.po.thread11;
public class MyThread1 extends Thread {
private MyService myService;
    public MyThread1(MyService myService) {
        this.myService = myService;
    }
    @Override
    public void run() {
        super.run();
        myService.testMethod();
    }
}
package com.it.po.thread11;
import com.it.po.thread10.*;
public class Run1 {
    public static void main(String[] args) throws InterruptedException {
        MyService myService = new MyService();
        MyThread1 my1 = new MyThread1(myService);
        MyThread1 my2 = new MyThread1(myService);
        MyThread1 my3 = new MyThread1(myService);
        MyThread1 my4 = new MyThread1(myService);
        my1.setName("A ");
        my2.setName("B ");
        my3.setName("C ");
        my4.setName("D ");
        my1.start();
        my2.start();
        my3.start();
        my4.start();


    }

}

 

线程 C  1
线程 C  2
线程 C  3
线程 C  4
线程 C  5
线程 B  1
线程 B  2
线程 B  3
线程 B  4
线程 B  5
线程 A  1
线程 A  2
线程 A  3
线程 A  4
线程 A  5
线程 D  1
线程 D  2
线程 D  3
线程 D  4
线程 D  5

 

当前线程打印完成之后释放锁,其他线程才可以打印

(二)、

Lock 线程同步

 

package com.it.po.thread11;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService2 {
    private Lock lock =new ReentrantLock();
    public void  methodA(){
        try {
            lock.lock();//加锁
            String name = Thread.currentThread().getName();
            System.out.println("methodA begin 线程 "+name+" time= "+System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("methodA end 线程 "+name+" time= "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();//释放锁
        }
    }
    public void  methodB(){
        try {
            lock.lock();//加锁
            String name = Thread.currentThread().getName();
            System.out.println("methodB begin 线程 "+name+" time= "+System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("methodB end 线程 "+name+" time= "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();//释放锁
        }
    }

}

 

 

 

 

 

 

 

 

package com.it.po.thread11;
public class Run2 {
    public static void main(String[] args) throws InterruptedException {
        MyService2 myService = new MyService2();
        MyThread2_1 my1 = new MyThread2_1(myService);
        MyThread2_2 my2 = new MyThread2_2(myService);
        MyThread2_3 my3 = new MyThread2_3(myService);
        MyThread2_4 my4 = new MyThread2_4(myService);
        my1.setName("A ");
        my2.setName("B ");
        my3.setName("C ");
        my4.setName("D ");
        my1.start();
        my2.start();
        my3.start();
        my4.start();
    }

}

 

methodA begin 线程 A  time= 1575471578684
methodA end 线程 A  time= 1575471583686
methodA begin 线程 B  time= 1575471583686
methodA end 线程 B  time= 1575471588686
methodB begin 线程 D  time= 1575471588686
methodB end 线程 D  time= 1575471593686
methodB begin 线程 C  time= 1575471593686
methodB end 线程 C  time= 1575471598686

 

三)奇怪的不同步

package com.it.po.thread11;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyService2 {
    private Lock lock =new ReentrantLock();
    public void  methodA(){
        try {
            lock.lock();//加锁
            String name = Thread.currentThread().getName();
            System.out.println("methodA begin 线程 "+name+" time= "+System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("methodA end 线程 "+name+" time= "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();//释放锁
        }
    }
    public void  methodB(){
        try {
            lock.lock();//加锁
            String name = Thread.currentThread().getName();
            System.out.println("methodB begin 线程 "+name+" time= "+System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("methodB end 线程 "+name+" time= "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();//释放锁
        }
    }
   synchronized public void  methodC(){
        try {
            String name = Thread.currentThread().getName();
            System.out.println("methodC begin 线程 "+name+" time= "+System.currentTimeMillis());
            Thread.sleep(5000);
            System.out.println("methodC end 线程 "+name+" time= "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }



}

 

package com.it.po.thread11;

public class MyThread2_5 extends Thread {
private MyService2 myService2;
    public MyThread2_5(MyService2 myService2) {
        this.myService2 = myService2;
    }
    @Override
    public void run() {
        super.run();
        myService2.methodC();
    }
}

 

package com.it.po.thread11;

public class Run2 {
    public static void main(String[] args) throws InterruptedException {
        MyService2 myService = new MyService2();
        MyThread2_1 my1 = new MyThread2_1(myService);
        MyThread2_2 my2 = new MyThread2_2(myService);
        MyThread2_3 my3 = new MyThread2_3(myService);
        MyThread2_4 my4 = new MyThread2_4(myService);
        MyThread2_5 my5 = new MyThread2_5(myService);
        my1.setName("A ");
        my2.setName("B ");
        my3.setName("C ");
        my4.setName("D ");
        my5.setName("E ");
        my1.start();
        my2.start();
        my3.start();
        my4.start();
        my5.start();
    }

}

 

 

methodA begin 线程 A  time= 1575472866023
methodC begin 线程 E  time= 1575472866023
methodA end 线程 A  time= 1575472871023
methodA begin 线程 B  time= 1575472871023
methodC end 线程 E  time= 1575472871024
methodA end 线程 B  time= 1575472876024
methodB begin 线程 C  time= 1575472876024
methodB end 线程 C  time= 1575472881024
methodB begin 线程 D  time= 1575472881024
methodB end 线程 D  time= 1575472886024

 

结论:

1、调用lock.lock();代码的线程就持有了 “  对象监视器” ,其他线程只有等待

2.lock.lock() 和 synchronized  锁 不一样导致不同步。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2019-12-01 18:23  源无极  阅读(189)  评论(0)    收藏  举报