昨日总结:

  1. 复习了实现多线程的三种方式
  2. 参加了卓望数码宣讲会以及笔试并进行复盘
  3. 按照内推人的建议修改了简历。

今日计划:

  1. 继续复习多线程
  2. 参加浩鲸宣讲会并投递简历
  3. 尝试性浏览系统后台管理项目并学习。

Lamda表达式学习:

函数式接口:

定义:如果一个接口只包含唯一一个抽象方法,那么它就是函数式接口。
而对于函数式接口,可以通过Lamda表达式创建该接口的对象。

new Thread(new A()).start()

    class A implements Runnable{
        @Override
        public void run() {
            System.out.println("123");
        }
    }
    new Thread(new A()).start();

这段代码中new Thread(new A()).start();实际上使用了静态代理。
代理对象和真实对象都要实现同一个接口,代理对象需要代理真实角色。
可以通过代理对原来的方法和功能进行附加和增强。

线程6状态

视频里说是5状态,但自己查了一下源码,发现其实是6状态,有可能是和操作系统的状态搞混了。

    public enum State {
        //新建一个线程时会进入此状态。
        NEW,
        //可运行的
        RUNNABLE,
        //阻塞态。当线程等待一个锁时会进入此状态,直到线程获得锁。
        BLOCKED,
        //等待。Object.wait()或Thread.join()会使得线程进入此状态。
        WAITING,
        //有时限的等待,线程处于等待状态,但是等待超过一定时间会进入RUNNABLE状态。除了使用Object.wait(long),Thread.join(long)之外也可以使用Thread.sleep(long)。
        TIMED_WAITING,
        //结束态,线程结束了他的使命。
        TERMINATED;
    }

死亡之后的线程不能再次启动。尝试启动会造成报错。

每个对象都有一把锁,Sleep不会释放锁。

Thread.yield()

线程礼让,让其他线程先执行。礼让不一定成功,看CPU调度。

Thread.join()

线程插队,使得其他线程进入等待态,直到该插队线程执行完毕。

线程优先级 (有效范围0-10)

main主线程默认线程优先级是5,线程优先级越高,越有可能被率先调度。
对于优先级的使用,要先设置优先级,再启动线程。否则会失效。

守护线程

线程分为守护线程和用户线程。
虚拟机必须等待用户线程执行完毕,而不必等待守护线程执行结束。
守护线程举例:GC垃圾回收线程,后台记录日志线程,监视内存线程。
当虚拟机只剩下守护线程的时候,虚拟机就会退出。

synchronized关键字

synchronized可以修饰代码块,也可以修饰实例方法。
当synchronized修饰实例方法时,锁定的是当前方法,其他线程不能访问该对象带有synchronized关键字的锁。因为一个对象只有一把锁,但是可以访问该对象的其他实例方法。多个对象每个对象都会有一把锁。

public class AccountingSyncBad implements Runnable{
    static int i=0;
    public synchronized void increase(){
        i++;
    }
    @Override
    public void run() {
        for(int j=0;j<1000000;j++){
            increase();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        //new新实例
        Thread t1=new Thread(new AccountingSyncBad());
        //new新实例
        Thread t2=new Thread(new AccountingSyncBad());
        t1.start();
        t2.start();
        //join含义:当前线程A等待thread线程终止之后才能从thread.join()返回
        t1.join();
        t2.join();
        System.out.println(i);
    }
}

· 如上案例中,虽然对increase()实例方法进行了synchronized修饰,但仍然无法起到该有的坐拥,因为这是两个不同的对象,所以只是分别对所处的对象方法进行加锁。解决方法是将该方法转变为静态方法。
· 当synchronized修饰静态方法时,锁的是该对象的class类对象,其他线程不能访问该类所属对象的方法直到获取该类所属对象的锁。
· 如果同时有两个线程分别操作同一个类下修饰实例方法的synchronized和修饰静态方法的synchronized,是允许的,因为修饰实例方法的synchronized是对实例对象进行加锁,而修饰静态方法的synchronized是对class类对象进行加锁。
· synchronized(this){}指对当前实例加锁。synchronized(xx.class){}则是对类对象进行加锁

死锁

死锁的四个必要条件:互斥,占有且等待,不可抢占,循环等待。

今日总结:

  • 复习(也算是学习了一些多线程相关的知识)
  • 参加浩鲸宣讲会并尝试提问,混了点HR印象,不知道到时候能不能用得上给自己的加分。

明日计划:

  • 准时参加4399笔试。
  • 跟进浩鲸内推进度,考虑是否多投一家棒谷应聘。
  • 继续学习多线程有关知识,并推进进度到JUC(java.util.concurrent)
  • 4399笔试复盘。