欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

day15_0711课堂笔记

程序员文章站 2024-03-21 22:53:10
...

day0711课堂笔记

1、比较器的回忆

  • 第一种:实现java.lang.Comparable接口。
  • 第二种:单独编写一个比较器Comparator接口。
  • TreeSet(Comparator) TreeMap Collections.sort(List,Comparator) Arrays.sort()需要指定比较规则

2、设计模式

模式:(前辈对代码的总结),实现代码的套路

单例模式:保证一个类只能有一个实例,如:任务管理器。

  • 懒汉式 : 实例等到调用方法时候创建(调用的时候,最后一刻)
  •  饿汉式: 类第一次加载之后就会创建实例
    
  •  	静态的内容(静态变量,静态块),在类第一次加载之后就会初始化
    

实现方式:3步

  • 1、构造器私有化
  • 2、私有的静态的该类的引用
  • 3、对外提供静态的公共的获取该引用的方法

饿汉式

public class DesignDemo01 {
    public static void main(String[] args) {
        System.out.println(Person.getInstance());
        System.out.println(Person.getInstance());
        System.out.println(Person.getInstance());
        System.out.println(Person.getInstance());//返回地址相同
    }
}

class Person {
    //2、静态的,私有的该类的引用
    private static Person person = new Person();

    //1、构造器私有化
    private Person() {
    }

    //3、对外部提供静态的,公开的一个获取引用方法
    public static Person getInstance(){
        return person;
    }

}

懒汉式

//懒汉式
public class DesignDemo02 {
    public static void main(String[] args) {
        System.out.println(Person1.getInstance());;
        System.out.println(Person1.getInstance());;
        System.out.println(Person1.getInstance());;
    }
}
class Person1 {
    //2、静态的,私有的该类的引用
    private static Person1 person1;;

    //1、构造器私有化
    private Person1() {
    }

    //3、对外部提供静态的,公开的一个获取引用方法
    public static Person1 getInstance(){
        //创建对象
        //第一次调用方法时候才创建对象,第二次开始就不创建,因为已经有了,直接返回
        if (person1 == null) {
            person1 = new Person1();
        }
        return person1;
    }

}

3、多线程

3.1多线程概念

​ 进程是一个应用程序(1个进程是一个软件)。进程是资源分配的最小单位。
​ 线程是一个进程中的执行场景/执行单元。CPU调度度最小单元。
​ 一个进程可以启动多个线程。

​ 线程和线程之间共享方法区和堆内存,但栈内存独立,栈之间互不干扰。

​ 多线程的优点:可以提高工作效率。缺点是设计复杂。

3.2如何实现多线程

第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法。
// 定义线程类
public class MyThread extends Thread{
public void run(){ }
}
// 创建线程对象
MyThread t = new MyThread();
// 启动线程。
t.start();

public class ThreadDemo01 extends Thread{//继承Thread类,并重写run方法
    //重写run方法
    @Override
    public void run(){
        for (int i = 0; i <50 ; i++) {
            System.out.println("i+"+i);
        }
    }

    public static void main(String[] args) {

        //创建线程对象
        ThreadDemo01 t = new ThreadDemo01();
        //开启线程
        t.start();

        //主线程中的代码
        for (int i = 0; i <1000 ; i++) {
            System.out.println("j+"+i);
        }
    }
}

第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法。
// 定义一个可运行的类
public class MyRunnable implements Runnable {
public void run(){
}
}
// 创建线程对象
Thread t = new Thread(new MyRunnable());
// 启动线程
t.start();

public class ThreadDemo02 {
    public static void main(String[] args) {
        Thread t = new Thread(new Demo());
        t.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main线程");
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
class Demo implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("其他线程");
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承
其它的类,更灵活。

第三种方式:实现Callable接口,重写call()方法。

3.3实现中使用内部类,lambda

package com.wse.thread03;
/*
 * 使用内部类,匿名内部类,Lambda开启线程
 */
public class Thread04 {
    //内部类
    static class InnerClass implements Runnable{

        @Override
        public void run() {
            for (int i = 0; i <10 ; i++) {
                System.out.println("内部类");
            }
        }
    }
    public static void main(String[] args) {
        Thread t1 = new Thread(new InnerClass());
        t1.start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                System.out.println("匿名内部类使用lambda");
            }
        }).start();
        for (int i = 10; i >=0 ; i--) {
            System.out.println(i);
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }


}

3.4线程状态

  • 新生状态:new的时候,线程处于新生状态
  • 就绪状态:start()线程就会进入到就绪状态,线程就会进入到就绪队列进行等待,等待cpu的调度
  • 运行状态:cpu把资源分配给这个线程,线程才能进入运行状态
  • 阻塞状态:sleep()可以让线程进入阻塞
  • 死亡状态:线程结束

注意:线程一旦进入阻塞状态,无法直接恢复运行,会重新进入就绪状态,线程一旦终止,无法恢复,重新创建不是原来的线程。

进入终止状态的情况

    1. stop destroy() 不推荐使用 2)通过标识判断–推荐 3)线程正常执行完毕

进入就绪状态的情况

    1. start()
    1. 阻塞解除
    1. 线程切换
    1. yield() 礼让线程

进入阻塞状态的情况

    1. sleep()
    1. wait()
    1. join()

礼让demo

package com.wse.thread03;

/**
 * 礼让线程 yield
 * 让出cpu资源 , 原线程直接 进入就绪 状态
 */
public class Thread05 extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "开始----------------------");
        Thread.yield();
        System.out.println(Thread.currentThread().getName() + "结束----------------------");
    }

    public static void main(String[] args) {
        Thread05 y = new Thread05();
        new Thread(y,"A").start();
        new Thread(y,"B").start();
        for (int i = 0; i < 200; i++) {
            if (i==100){
             Thread.yield();
            }
            System.out.println(i);
        }
    }
}

插队线程

3.5线程的同步