Java中的线程的状态、线程休眠、同步锁、死锁、Lock接口、匿名内部类(基础解析)

    创建一个线程 相当于CPU开辟了一个独立的执行路径
    每个执行路径都是一个独立的空间
    创建一个线程 该线程就会拥有一个独立的栈空间
    如果在同一个栈空间中 不符合先入栈后出栈规则
    线程的六种状态
        1.新建状态(new 线程对象)
        2.运行状态(调用 start方法)
        3.受阻塞状态(等待CPU的执行资源)
        4.休眠状态(调用了sleep(时间)方法)
        5.等待状态(调用了wait方法)
        6.死亡状态(润方法执行完毕)

 线程的状态图

匿名内部类

    相当于创建一个该类的子类的对象
    new 父类类名或接口名(){
        重写父类的方法
    };
    public class Demo {
        public static void main(String[] args){
            // 创建Test类的子类对象
            // 这里可以直接new Test(){}
            // 但是这样这个对象没有名字 是匿名对象
            // 可以接收一下
            Test test = new Test(){
                //重写父类的方法
                @Override
                public void fun(){
                    System.out.println("我是子类的fun方法");
                }
            };
            // 调用子类方法
            test.fun();
        }
    }

    class Test{
        public void fun(){
            System.out.println("我是父类的fun方法");
        }
    }
    public class Demo {
         public static void main(String[] args) {
             // 创建接口的实现类
             new TestInter() {
                 @Override
                 public void fun(){
                     System.out.println("我是实现类的 fun方法");
                 }
             }.fun();
         }
    }

    interface TestInter {
        public abstract void fun();
    }
匿名内部类方式创建线程
    方式1
    public class Demo {
        public static void main(String[] args) {
            new Thread() {
                @Override
                public void run() {
                    System.out.println("我是创建线程方式1");
                }
            }.start();

            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("我是创建线程方式2");
                }
            };
            //放入线程对象中
            Thread thread = new Thread(runnable);
            thread.start();

            new Thread(new Runnable() {
                @Override
                public void run(){
                    System.out.println("我是创建线程方式3");
                }
            }).start();
        }
    }

线程休眠

    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            SleepThread sleepThread = new SleepThread();
            sleepThread.start();
            for (int i = 0; i < 100; i++) {
                // 线程休眠1s 单位是 毫秒
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + i);
            }
        }
    }
    class SleepThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 50; i++) {
                // 休眠1s
                // 如果在子线程中出现异常 只能try...catch处理
                /*
                 * Thread类是Runnable接口的实现类
                 * 重写了接口中的run方法
                 * 该方法 没有抛出异常
                 * 所以 所有Runnable接口的实现类(包括Thread类)
                 * 都不能在run方法中 抛出异常 只能处理
                 */
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + i);
            }
        }
    }

同步锁

    /*
     * 卖火车票问题
     */
    public class Demo05 {
        public static void main(String[] args) {
            TicketsRunnable tr = new TicketsRunnable();
            // 创建3个线程 这个线程 会执行run方法(这个线程的任务)
            Thread t1 = new Thread(tr);
            Thread t2 = new Thread(tr);
            Thread t3 = new Thread(tr);
            // 开启这三个线程
            t1.start();
            t2.start();
            t3.start();
        }
    }

/*
 * 同步锁(同步代码块)
 * 锁 可以是任意对象  要保证 锁的唯一 三个线程都使用的是同一把锁
 * 
 * 
 * synchronized (对象锁) {

            }
 */
    class TicketsRunnable implements Runnable{
        //声明50张票 保证票是共享数据 只new 一次该类对象
        private int tickets = 50;
        // 创建了对象锁 保证唯一
        private Object obj = new Object();

        //卖票方法
        @Override
        public void run() {
            while (true) {
                // 锁只要保证是对象和唯一 就可以 (填this也可以)
                synchronized (obj) {
                    // 操作的共享数据的代码
                    if (tickets > 0) {
                        // 线程休眠一会儿
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        // 有票就卖一张
                        System.out.println(Thread.currentThread().getName() + "--" + tickets);
                        // 减少一张
                        tickets--;
                    }else {
                        // 没票 结束循环
                        break;
                    }
                }
                // 让线程 让出CPU的资源
                // 不是一定让出 有几率
                Thread.yield();

            }
        }
    }
方法中添加 synchronized 关键词
    *
    * 同步锁规则:  
    *   如果有锁 可以进同步代码块 携带锁进去 
    *   当线程执行完同步代码块中的代码 把锁还回去
    *   如果没有锁 线程需要在同步代码块外等待 遇到锁才可以近同步代码块             
    */
    public class Demo06 {
        public static void main(String[] args) {
            TicketsRunnable1 tr1 = new TicketsRunnable1();
            // 创建3个线程 这个线程 会执行run方法(这个线程的任务)
            Thread t1 = new Thread(tr1);
            Thread t2 = new Thread(tr1);
            Thread t3 = new Thread(tr1);
            // 开启这三个线程
            t1.start();
            t2.start();
            t3.start();
        }
    }

    class TicketsRunnable1 implements Runnable {
        // 声明50张票 保证票是共享数据 只new 一次该类对象
        private int tickets = 50;
        // 创建了对象锁 保证唯一
        private Object obj = new Object();

        // 卖票方法
        @Override
        public void run() {
            while (true) {
                if (sellTickets()) {
                    break;
                }
                // 让出CPU资源
                Thread.yield();
            }
        }

        // 操作共享数据的方法
        // 在方法中 添加 synchronized 关键词
        public synchronized boolean sellTickets() {

            // 操作的共享数据的代码
            if (tickets > 0) {
                // 线程休眠一会儿
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 有票就卖一张
                System.out.println(Thread.currentThread().getName() + "--" + tickets);
                // 减少一张
                tickets--;
                return false;
            } else {
                // 没票 结束循环
                return true;
            }
        }
    }   
静态的同步代的码锁
    public class Demo06 {
    public static void main(String[] args) {
        TicketsRunnable1 tr1 = new TicketsRunnable1();
        // 创建3个线程 这个线程 会执行run方法(这个线程的任务)
        Thread t1 = new Thread(tr1);
        Thread t2 = new Thread(tr1);
        Thread t3 = new Thread(tr1);
        // 开启这三个线程
        t1.start();
        t2.start();
        t3.start();
    }
}

class TicketsRunnable1 implements Runnable {
    // 声明50张票 保证票是共享数据 只new 一次该类对象
     private static int tickets = 50;
    // 创建了对象锁 保证唯一
    private Object obj = new Object();

    // 卖票方法
    @Override
    public void run() {
        while (true) {
            if (sellTickets()) {
                break;
            }
            // 让出CPU资源
            Thread.yield();
        }
    }


     //静态方法的同步代码的锁 可以使用本类 类名.class
     public static boolean sellTickets() {
        synchronized (TicketsRunnable1.class) {
        // 操作的共享数据的代码
            if (tickets > 0) {
            // 线程休眠一会儿
            try {
                Thread.sleep(10);
                 } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
                 }
             // 有票就卖一张
             System.out.println(Thread.currentThread().getName() + "--" + tickets);
            // 减少一张
             tickets--;
             return false;
             } else {
            // 没票 结束循环
            return true;
             }
         }
     }
}
死锁
    /*
     * 模拟线程死锁
    * 1.需要两个锁对象( 保证唯一)
     */
    public class Demo07 {
        public static void main(String[] args) {
            DeathLockRunnable dlr = new DeathLockRunnable();
            Thread t1 = new Thread(dlr);
            Thread t2 = new Thread(dlr);
            t1.start();
            t2.start();
        }
    }
    // A锁
    class LockA {
        // 私有构造方法
        private LockA() {

        }
        // 定义一个常量 作为 锁对象 不能修改 也不能创建
        public static final LockA LOCK_A = new LockA();
    }
    // B锁
    class LockB{
        //私有构造方法
        private LockB() {

        }
        // 定义一个常量 作为 锁对象 不能修改 也不能创建
        public static final LockB LOCK_B = new LockB();
    }

    class DeathLockRunnable implements Runnable{
        // 声明一个标识
        // 标记一次是先A后B
        //    一次是先B后A
        private boolean isTrue = true;
        @Override
        public void run() {
            // 死循环(增加死锁的几率)
            while (true) {
                if (isTrue) {
                    // A --> B
                    synchronized (LockA.LOCK_A) {
                        System.out.println("if...LOCK_A");
                        synchronized (LockB.LOCK_B) {
                            System.out.println("if...LOCK_B");
                        }
                    }
                } else {
                    // B --> A
                    synchronized (LockB.LOCK_B) {
                        System.out.println("else...LOCK_B");
                        synchronized (LockA.LOCK_A) {
                            System.out.println("else...LOCK_A");
                        }
                    }
                }
                // 修改标记
                isTrue = !isTrue;
            }
        }
    }

Lock 接口

    Lock 是jdk1.5之后出现的锁
    使用LockLock.lock();
    try{
        写操作共享数据的代码
    }finally{
        lock.unlock();
    }
    public class Demo {
        public static void main(String[] args) {
            Tickets3 tickets3 = new Tickets3();
            Thread t1 = new Thread(tickets3);
            Thread t2 = new Thread(tickets3);
            Thread t3 = new Thread(tickets3);
            t1.start();
            t2.start();
            t3.start();
        }
    }
    class Tickets3 implements Runnable{
        private int tickets = 50;
        //声明锁对象
        private ReentrantLock lock = new ReentrantLock();
        @Override
        public void run() {
            while (true) {
                // 加锁
                lock.lock();
                try {
                    // 锁住操作共享数据的代码
                    if (tickets > 0) {
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + ":" + tickets);
                        tickets--;
                    }else {
                        break;
                    }
                } finally {
                    // 解锁
                    lock.unlock();
                }
                // 让出CPU资源
                Thread.yield();
            }
        }
    }

接口实现创建线程的好处

    1.避免直接集成Thread类的局限性(避免单继承)
    2.接口即插即用 减少类与类之间联系(可以解耦)


                                        Day.29

http://blog.csdn.net/ssssssue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值