day24

作者: 姗婷 | 来源:发表于2020-12-19 19:11 被阅读0次

    1:多线程(理解)

    (1)JDK5以后的针对线程的锁定操作和释放操作

    Lock锁:
    void lock(): 获取锁。
    void unlock():释放锁

    (2)死锁问题的描述和代码体现

    public class DieLockDemo {
        public static void main(String[] args) {
            DieLock dl1 = new DieLock(true);
            DieLock dl2 = new DieLock(false);
    
            dl1.start();
            dl2.start();
        }
    }
    
    public class MyLock {
        // 创建两把锁对象
        public static final Object objA = new Object();
        public static final Object objB = new Object();
    }
    
    public class DieLock extends Thread {
    
        private boolean flag;
    
        public DieLock(boolean flag) {
            this.flag = flag;
        }
    
        @Override
        public void run() {
            if (flag) {
                synchronized (MyLock.objA) {
                    System.out.println("if objA");
                    synchronized (MyLock.objB) {
                        System.out.println("if objB");
                    }
                }
            } else {
                synchronized (MyLock.objB) {
                    System.out.println("else objB");
                    synchronized (MyLock.objA) {
                        System.out.println("else objA");
                    }
                }
            }
        }
    }
    

    (3)生产者和消费者多线程体现(线程间通信问题)

    以学生作为资源来实现的
    资源类:Student
    设置数据类:SetThread(生产者)
    获取数据类:GetThread(消费者)
    测试类:StudentDemo
    代码:
    A:最基本的版本,只有一个数据。
    B:改进版本,给出了不同的数据,并加入了同步机制
    C:等待唤醒机制改进该程序,让数据能够实现依次的出现
    wait()
    notify()
    notifyAll() (多生产多消费)
    D:等待唤醒机制的代码优化。把数据及操作都写在了资源类中

    public class Student {
        private String name;
        private int age;
        private boolean flag; // 默认情况是没有数据,如果是true,说明有数据
    
        public synchronized void set(String name, int age) {
            // 如果有数据,就等待
            if (this.flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            // 设置数据
            this.name = name;
            this.age = age;
    
            // 修改标记
            this.flag = true;
            this.notify();
        }
    
        public synchronized void get() {
            // 如果没有数据,就等待
            if (!this.flag) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            // 获取数据
            System.out.println(this.name + "---" + this.age);
    
            // 修改标记
            this.flag = false;
            this.notify();
        }
    }
    
    public class SetThread implements Runnable {
    
        private Student s;
        private int x = 0;
    
        public SetThread(Student s) {
            this.s = s;
        }
    
        @Override
        public void run() {
            while (true) {
                if (x % 2 == 0) {
                    s.set("林青霞", 27);
                } else {
                    s.set("刘意", 30);
                }
                x++;
            }
        }
    }
    
    public class GetThread implements Runnable {
        private Student s;
    
        public GetThread(Student s) {
            this.s = s;
        }
    
        @Override
        public void run() {
            while (true) {
                s.get();
            }
        }
    }
    
    public class StudentDemo {
        public static void main(String[] args) {
            //创建资源
            Student s = new Student();
            
            //设置和获取的类
            SetThread st = new SetThread(s);
            GetThread gt = new GetThread(s);
    
            //线程类
            Thread t1 = new Thread(st);
            Thread t2 = new Thread(gt);
    
            //启动线程
            t1.start();
            t2.start();
        }
    }
    

    (4)线程组

    把多个线程组合到一起。
    线程默认情况下属于main线程组

    (5)线程池

    线程池的好处:线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。
    如何实现线程的代码呢?
    A:创建一个线程池对象,控制要创建几个线程对象。
    public static ExecutorService newFixedThreadPool(int nThreads)
    B:这种线程池的线程可以执行:
    可以执行Runnable对象或者Callable对象代表的线程
    做一个类实现Runnable接口。
    C:调用如下方法即可
    Future<?> submit(Runnable task)
    <T> Future<T> submit(Callable<T> task)
    D:我就要结束,可以吗?
    可以。pool.shutdown();

    (6)多线程实现的第三种方案

    (7)多线程的面试题

    public class ThreadDemo {
        public static void main(String[] args) {
            // 继承Thread类来实现多线程
            new Thread() {
                public void run() {
                    for (int x = 0; x < 100; x++) {
                        System.out.println(Thread.currentThread().getName() + ":"
                                + x);
                    }
                }
            }.start();
    
            // 实现Runnable接口来实现多线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int x = 0; x < 100; x++) {
                        System.out.println(Thread.currentThread().getName() + ":"
                                + x);
                    }
                }
            }) {
            }.start();
    }
    

    1:多线程有几种实现方案,分别是哪几种?

    两种。继承Thread类、实现Runnable接口
    扩展一种:实现Callable接口。这个得和线程池结合。
    

    2:同步有几种方式,分别是什么?

    两种。同步代码块、同步方法
    

    3:启动一个线程是run()还是start()?它们的区别?

    start();
    run():封装了被线程执行的代码,直接调用仅仅是普通方法的调用
    start():启动线程,并由JVM自动调用run()方法

    4:sleep()和wait()方法的区别

    sleep():必须指时间;不释放锁。
    wait():可以不指定时间,也可以指定时间;释放锁。

    5:为什么wait(),notify(),notifyAll()等方法都定义在Object类中

    因为这些方法的调用是依赖于锁对象的,而同步代码块的锁对象是任意锁。
    而Object代码任意的对象,所以,定义在这里面。
    6:线程的生命周期图
    新建 -- 就绪 -- 运行 -- 死亡
    新建 -- 就绪 -- 运行 -- 阻塞 -- 就绪 -- 运行 -- 死亡
    建议:画图解释。


    图片.png

    2:设计模式(理解)

    (1)面试对象的常见设计原则

    单一
    开闭
    里氏
    依赖注入
    接口
    迪米特

    (2)设计模式概述和分类

    A:经验的总结
    B:三类
    创建型
    结构型
    行为型

    (3)改进的设计模式

    A:简单工厂模式
    B:工厂方法模式
    C:单例模式(掌握):
    饿汉式:类一加载就创建对象
    懒汉式:用的时候,才去创建对象
    面试题:单例模式的思想是什么?请写一个代码体现。

    开发:饿汉式(是不会出问题的单例模式)
    面试:懒汉式(可能会出问题的单例模式)
    A:懒加载(延迟加载)
    B:线程安全问题
    a:是否多线程环境 是
    b:是否有共享数据 是
    c:是否有多条语句操作共享数据 是

    a:以下是饿汉式

    public class Student {
        private Student() {}
        private static Student s = new Student();
        public static Student getStudent(){
            return s;
        }
    }
    public class StudentDemo {
        public static void main(String[] args) {
            Student s1 = Student.getStudent();
            Student s2 = Student.getStudent();
            System.out.println(s1 == s2);
        }
    }
    
            b:懒汉式
    
    public class Teacher {
        private Teacher() { }
    
        private static Teacher t = null;
    
        public synchronized static Teacher getTeacher(){
            if (t == null){
                t = new Teacher();
            }
                return t;
        }
    }
    public class TeacherDemo {
        public synchronized static void main(String[] args) {
            Teacher t1 = Teacher.getTeacher();
            Teacher t2 = Teacher.getTeacher();
            System.out.println(t1 == t2);
        }
    }
    

    (4)Runtime

        JDK提供的一个单例模式应用的类。
        还可以调用dos命令。
    

    相关文章

      网友评论

          本文标题:day24

          本文链接:https://www.haomeiwen.com/subject/mbpcnktx.html