Lock 和 synchronized的区别

1、线程生命周期

线程总共有5大状态

  • 新建状态:新建线程对象,并没有调用start()方法之前

  • 就绪状态:调用start()方法之后线程就进入就绪状态,但是并不是说只要调用start()方法线程就马上变为当前线程,在变为当前线程之前都是为就绪状态。值得一提的是,线程在睡眠和挂起中恢复的时候也会进入就绪状态哦。

  • 运行状态:线程被设置为当前线程,开始执行run()方法。就是线程进入运行状态

  • 阻塞状态:线程被暂停,比如说调用sleep()方法后线程就进入阻塞状态

  • 死亡状态:线程执行结束

  

锁类型

 

  • lock():获取锁,如果锁被暂用则一直等待

  • unlock():释放锁

  • tryLock(): 注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true

  • tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间

  • lockInterruptibly():用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事

 

package cn.xiang.thread.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * lock锁学习demo
 * 总结:
 *         1、使用lock.lock()方法可以将对象锁定。同时必须在finally将锁释放lock.unlock(),否则其他对象获取不了该锁。
 *         2、如果是线程内新定义的对象,那么有无锁都会异步执行,并不同步。
 * @author 向宁
 *日期:2018年4月11日
 *时间:下午3:26:06
 *
 */
public class LockDemo01 {
    /**
     * 创建锁
     */
    private Lock lock = new ReentrantLock();
    
    /**
     * 需要同步执行的方法
     * @param thread
     * @throws InterruptedException 
     */
    public void lockMethod(){
        System.out.println("还没开始锁定");
        lock.lock();
        Thread thread = Thread.currentThread();
        System.out.println("我是" + thread.getName() + "!正在使用锁");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
        
    }
    
    public static void main(String[] args) {
        final LockDemo01 lockDemo = new LockDemo01();
        Thread t1 = new Thread(){
            @Override
            public void run(){
                lockDemo.lockMethod();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run(){
                lockDemo.lockMethod();
            }
        };
        t1.start();
        t2.start();
    }
}
LockDemo01

结果如下:

  

 

package cn.xiang.thread.lock;
/**
 * lock.tryLock()
 *         可if判断该代码是否被锁定。如果被锁定,则不执行。
 * lock.tryLock(time, unit)
 *         给一个等待时间,等待时间过后,如果锁定被释放,则可以直接进入。如果等待时间已过,还不释放。则直接执行else
 * 
 */

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo02 {
    private Lock lock = new ReentrantLock();
    /**
     * 需要同步的方法
     */
    public void lockMethod(){
        try {
            System.out.println("开始执行方法");
            if (lock.tryLock(1, TimeUnit.SECONDS)) {
                //如果当前已经被锁定
                try {
                    System.out.println("我是线程:" + Thread.currentThread().getName() + "!我已经拿到了该锁!");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally{
                    lock.unlock();
                }
                
            }else{
                System.out.println("我是线程:" + Thread.currentThread().getName() + "!我没有拿到该锁,就不要了!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        final LockDemo02 lockDemo = new LockDemo02();
        Thread t1 = new Thread(){
            @Override
            public void run(){
                lockDemo.lockMethod();
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run(){
                lockDemo.lockMethod();
            }
        };
        Thread t3 = new Thread(){
            @Override
            public void run(){
                lockDemo.lockMethod();
            }
        };
        t1.start();
        t2.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        t3.start();
    }
}
LockDemo02

结果如下:

  

 

 

以下是一个简单的死锁

package cn.xiang.thread;

public class ThreadDeadLock03 {
    
    public static void main(String[] args) {
        LockDemo04 lock = new LockDemo04(false);
        new Thread(lock).start();
        new Thread(lock).start();
        
    }
}

class LockDemo04 implements Runnable{
    private boolean flag;
    private Object obj1 = new Object();
    private Object obj2 = new Object();
    public LockDemo04(boolean flag){
        this.flag = flag;
    }
    @Override
    public void run() {
        flag = !flag;
        try {
            if(flag){
                synchronized(obj1){
                    System.out.println("已经拿到obj1的对象锁");
                    Thread.sleep(1000);
                    System.out.println("准备拿obj2的对象锁");
                    synchronized(obj2){
                        System.out.println("已经拿到obj2的对象锁,表示没有发生死锁");
                    }
                }
            }else{
                synchronized(obj2){
                    System.out.println("已经拿到obj2的对象锁");
                    Thread.sleep(1000);
                    System.out.println("准备拿obj1的对象锁");
                    synchronized(obj1){
                        System.out.println("已经拿到obj1的对象锁,表示没有发生死锁!");
                    }
                }
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

 

效果:

  

 

posted @ 2018-04-11 16:27  项羽齐  阅读(159)  评论(0编辑  收藏  举报