java多线程

线程的六种状态

1.线程的六种状态
    1.新建状态(new 线程对象)
    2.运行状态(调用start)
    3.受阻塞状态(等待cpu的执行资源)
    4.休眠状态(调用了sleep(休眠时间)方法)
    5.等待状态(调用了wait()方法)
    6.死亡状态(run()方法执行完毕)

这里写图片描述

匿名内部类方式创建线程

2.匿名内部类创建线程(三种方式)
    //第一种
    Thread t1 = new Thread(){
        @Override
        public void run(){
            System.out.println("创建线程方式1");
        }
    }; 
    t1.start();

    //第二种
    Runnable runnable = new Runnable(){
        public void run(){
         System.out.println("创建线程方式2");
        }
    };
    // 放入线程对象中
    Thread t2 = new Thread(runnable);
    t2.start();

    //第三种
    Thread t3 = new Thread(new Runnable () {
        @Override
        public void run(){
        System.out.println("创建线程方式3");
        }
    });
    t3.start();
3.    /*
      * 利用内部匿名类方式
      * 给TreeSet集合中的学生对象 按年龄排序
      * 学生: 姓名 年龄
      */
    // 创建Comparator接口的实现类对象
    Comparator<Student> comparator = new  Comparator<Student>(){
        @Override
        public int compare(Student o1, Student o2){
            return o1.getAge - o2.get.Age();
        }
    };
    // 创建集合 把实现类的对象放进集合中
    TreeSet<Student> set = new TreeSet<>(comparator);
        set.add(new Student("张三", 18));
        set.add(new Student("李四", 15));
        set.add(new Student("王五", 14));
        set.add(new Student("赵六", 20));
        for (Student student : set) {
            System.out.println(student);
        }

线程的休眠

4. // 主线程的休眠
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            // 线程休眠1秒 单位毫秒
            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++) {
            // 休眠一秒
            // 如果子线程中 出现异常 只能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);
        }   

对象锁(卖票问题)

5./*
    * 同步锁(同步代码块)
    * 锁可以是任意对象 只要保证锁的唯一性 让线程使用的是同一把锁
    * synchronized(对象锁){
    * 
    * }
    */
    class Ticket 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();
        }
    }
    //在main函数中测试
    public static void main(String[] args) {
        Ticket t = new Ticket();
        // 创建一个线程 这个线程会执行run方法(这条线程的任务)
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        //开启三个线程
        t1.start();
        t2.start();
        t3.start();
    }

线程死锁

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

}
class LockB{
    private LockB() {
    }
    public static final LockB LOCK_B = new LockB();
}
// 线程
class DieLock 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;
        }
    }
}
    // 在main函数中测试
    public static void main(String[] args) {
        DieLock dieLock = new DieLock();
        Thread t1 = new Thread(dieLock);
        Thread t2 = new Thread(dieLock);
        t1.start();
        t2.start();
    }

Lock锁

7.Lock锁
/*
 * jdk 1.5以后
 * lock 接口
 * Lock锁
 * 写法:
 * lock.lock();
 * try{
 *      写操作共享数据的代码
 * }finally{
 *      lock.unlock();
 * }
 * 
 * 1.接口实现创建线程的好处:避免了直接继承Thread类的局限性(避免单继承)
 * 2.接口 即插即用 减少类与类之间的联系(可以解耦)
 */
 // 借用卖票问题 使用Lock锁
 class Tickets 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) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + tickets);
                    tickets--;
                }else {
                    break;
                }
            } finally {
                // 解锁
                lock.unlock();
            }
            //Thread.yield();
        }
    }
}
    // 在main函数中测试
    Tickets tickets = new Tickets();
        Thread t1 = new Thread(tickets);
        Thread t2 = new Thread(tickets);
        Thread t3 = new Thread(tickets);
        t1.start();
        t2.start();
        t3.start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值