线程锁 和 同步锁规则 模拟线程死锁 和Lock锁

             买火车票的问题
                 主线程 
         三条分支线程 
         同步锁 同步代码块
         对象锁的对象 可以是任意对象  但是要保证锁的唯一  多个线程 都要使用 同一把锁   但是只有一把钥匙
         synchronized( 对象锁 ){

         }
             同步锁规则 : 如果没有锁需要在外面等待   
         如果有锁可以进去 携带锁进去
             等出了代码块要把锁还回去

public class Test {
            public static void main(String[] args) {
                TitkesRunnable tRunnable = new TitkesRunnable();
                //创建一个线程  这个线程会执行 run方法 (会执行这条线程的任务)
                Thread t1 =  new Thread(tRunnable);
                Thread t2 =  new Thread(tRunnable);
                Thread t3 =  new Thread(tRunnable);
                //开启三个线程
                t1.start();
                t2.start();
                t3.start();
            }
}

class TitkesRunnable implements Runnable{
    //声明50张票票  保证票是共享数据  只New一次该类对象
    //同步锁可以解决
    private int titkes = 50;
    //创建了对象锁并且保证了锁的唯一性
    private Object obj = new Object();
    //卖票方法
    @Override
    /*
     * 同步锁 同步代码块
     * 对象锁的对象 可以是任意对象  但是要保证锁的唯一  多个线程 都要使用 同一把锁   但是只有一把钥匙
     * synchronized( 对象锁 ){
     * 
     * }
     * @see java.lang.Runnable#run()
     */
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            //只要保证是对象  和 唯一的对象就可以  填this  可以
            synchronized (obj) {
                //操作的共有共享数据的代码
                if (titkes>0) {
                    //在打印之前让线程休眠一会  增加线程访问的时间 扩大出问题的几率
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    //有票就卖一张
                    System.out.println(Thread.currentThread().getName()+titkes);
                    //减少一场
                    titkes--;
                }else {
                    //没票就不卖 结束循环
                    break;
                }
            }
            //让线程放弃Cpu的资源
            Thread.yield();
        }
    }

}

同步锁规则


         同步锁规则
         线程 遇到锁 就进 进代码块(并且携带锁)
         当线程 执行完代码块中的代码 把锁返还
         线程 没有遇到锁 会在同步代码块外等着 遇到锁才能进 
         静态方法的  同步代码块的锁  可以使用本类  类名.class

public class Test2 {
            public static void main(String[] args) {
                TitkesRunnable tRunnable = new TitkesRunnable();
                //创建一个线程  这个线程会执行 run方法 (会执行这条线程的任务)
                Thread t1 =  new Thread(tRunnable);
                Thread t2 =  new Thread(tRunnable);
                Thread t3 =  new Thread(tRunnable);
                //开启三个线程
                t1.start();
                t2.start();
                t3.start();
            }
}
class TitkesRunnable1 implements Runnable{
    //声明50张票票  保证票是共享数据  只New一次该类对象
    //同步锁可以解决
    private int titkes = 50;
    //创建了对象锁并且保证了锁的唯一性
    private Object obj = new Object();
    //卖票方法
    @Override
    /*
     * 同步锁 同步代码块
     * 对象锁的对象 可以是任意对象  但是要保证锁的唯一  多个线程 都要使用 同一把锁   但是只有一把钥匙
     * synchronized( 对象锁 ){
     * 
     * }
     * @see java.lang.Runnable#run()
     */
    public void run() {
        while (true) {
            if (sellTitkes()) {
                break;
            }
            //让出cpu资源
            Thread.yield();
        }

    }
    //方法操作共享数据的方法
    //在方法中添加 synchronized 关键字 把方法 变成   同步方法
    //synchronized修饰的同步方法 一定有锁
    public synchronized boolean sellTitkes() {
        if (titkes>0) {
            //在打印之前让线程休眠一会  增加线程访问的时间 扩大出问题的几率
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            //有票就卖一张
            System.out.println(Thread.currentThread().getName()+"---"+titkes);
            //减少一场
            titkes--;
            //没卖完
            return false;
        }else {
            //没票就不卖 结束循环
            return true;
        }
    }
}

          模拟线程死锁
          1.需要两个锁对象(并且保证唯一)


public class Test3 {
            public static void main(String[] args) {
                DidLockRunnable didLockRunnable = new DidLockRunnable();
                Thread LonkOne = new Thread(didLockRunnable);
                Thread LonkTwo = new Thread(didLockRunnable);
                LonkOne.start();
                LonkTwo.start();
            }
}
//第一个锁
class LonkOne{
    //私有构造方法
    private LonkOne() {

    }
    //定义一个常量 不能被修改也不能被创建
    public static final LonkOne LONK_ONE = new LonkOne();
}

//第二个锁
class LonkTwo{
    private LonkTwo() {

    }
    //定义一个常量 不能被修改也不能被创建
    public static final LonkTwo LONK_TWO = new LonkTwo();
}
class DidLockRunnable implements Runnable{
            //声明一个标记
            //一次先走LonkOne 再走LonkTwo
            //一次先走LonkTwo 再走LonkOne
    public boolean  isTrue = true;
    @Override
    public void run() {
        //死循环(增加死锁率)
        while (true) {
            //按照标记走
            if (isTrue) {
                //让他走LonkOne --> LonkTwo
                synchronized (LonkOne.LONK_ONE) {
                    System.out.println("is....LONK_ONE");
                    synchronized (LonkTwo.LONK_TWO) {
                        System.out.println("is....LONK_TWO");
                    }
                }
                //让他走LonkTwo --> LonkOne
            }else {
                synchronized (LonkTwo.LONK_TWO) {
                    System.out.println("is....LONK_TWO");
                    synchronized (LonkOne.LONK_ONE) {
                        System.out.println("is....LONK_ONE");
                    }
                }
            }
            //修改标记
            isTrue = !isTrue;
        }

    }

}
          jdk 1.5 之后出现的锁
          Lock
           使用Lock锁
           lock.lock();
           try{

           }finally{
             lock.unlock();
           }
          接口实现 创建 线程的好处:
          1. 避免了直接继承Thread类的局限性  (避免单继承)
          2. 接口即插即用  减少 类与类之间的联系(可以解耦)

public class Test4 {
        public static void main(String[] args) {
            Titkets3 titkets3 = new Titkets3();
            Thread s1Thread= new Thread(titkets3);
            Thread s2Thread= new Thread(titkets3);
            Thread s3Thread= new Thread(titkets3);
            s1Thread.start();
            s2Thread.start();
            s3Thread.start();

        }
}
class Titkets3 implements  Runnable{
    private  int titkets  = 50;
    //声明所对象  声明成成员变量
    private  ReentrantLock  Lock  = new ReentrantLock();
    public void run() {
        while (true) {
            Lock.lock();
            try {
                //要锁住操作共享数据的代码
                if (titkets>0) {
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"--"+titkets);
                    titkets--;
                }else {
                    break;
                }
            } finally {
                // TODO: handle finally clause
                //解锁
                Lock.unlock();
            }
            //让出cpu资源
            Thread.yield();
        }

    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值