JavaSE 线程知识点学习整理

一.并发:指两个或多个事件在同一个时间段内发生;
并行:指两个或多个事件在同一时刻发生。

二.程序/进程/线程区别:
程序:软件【例:QQ】
进程:运行中的程序【运行QQ】
(是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,
⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是
系统运⾏程序的基本单位;系统运⾏⼀个程序即是⼀个进程从创建、运⾏
到消亡的过程。)
线程:进程中的任务【QQ打开了多个聊天窗口】
(线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程
中⾄少有⼀个线程。⼀个进程中是可以有多个线程的,这个应⽤程序也可
以称之为多线程程序。)cpu处理线程不是同时处理的,所谓”同时“是
因为切换速度快。

三.实现线程方法一:
定义Thread类的⼦类,并重写该类的run()⽅法,该
run()⽅法的⽅法体就代表了线程需要完成的任务,因此把run()⽅法称
为线程执⾏体。创建Thread⼦类的实例,即创建了线程对象。调⽤线
程对象的start()⽅法来启动该线程。
方法二:
1. 定义Runnable接⼝的实现类,并重写该接⼝的run()⽅法,该run()⽅法的⽅法体同样是该线
程的线程执⾏体。
2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该
Thread对象才是真正的线程对象。
3. 调⽤线程对象的start()⽅法来启动线程。
方法三:匿名内部类实现线程。

四.Thread 和 Runnable 的区别
如果⼀个类继承 Thread,则不适合资源共享。但是如果实现了 Runable 接⼝的话,则很容易的
实现资源共享。
总结:
实现 Runnable 接⼝⽐继承 Thread 类所具有的优势:
1. 适合多个相同的程序代码的线程去共享同⼀个资源。
2. 可以避免 java 中的单继承的局限性。
3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独⽴。
4. 线程池只能放⼊实现 Runable 或 Callable 类线程,不能直接放⼊继承 Thread 的类。

五.锁:代码就两种(ReentrantLock、synchronized),但是概念有很多种(乐观锁、悲观锁、公平锁等)。

例:

public class Ticket {
    int ticket=100;
    ReentrantLock locker=new ReentrantLock();//将锁放在sale()方法外,保证每个线程用的都是同一个锁
    public /*synchronized*/ void sale(){
        /*synchronized (this)*/ {//加锁,保证线程安全,但是牺牲效率。StringBuilder不加锁,效率高,StringBuffer加锁,线程安全但是牺牲效率。
            locker.lock();//ReentrantLock加锁
            if (ticket > 0) {
                try {
                    Thread.sleep((int) (Math.random() * 100));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("余票:" + (ticket--) + " " + Thread.currentThread().getName() + "正在卖票...");
                System.out.println(Thread.currentThread().getName() + "已卖出!");
            }
            locker.unlock();//ReentrantLock解锁
        }
    }
}

六.sleep和wait的区别:
带锁(sleep)和不带锁(wait)。

七.线程池: Executor
  工厂类: Executors
    static ExecutorService    newCachedThreadPool()
    static ExecutorService    newFixedThreadPool(int nThreads)
    static ScheduledExecutorService    newScheduledThreadPool(int corePoolSize)
    static ExecutorService    newSingleThreadExecutor()

    ExecutorService(I) extends Executor(I)
        Future submit(Callable/Runnable)
        void execute(Runnable)
    Future: Object get() -> 获得call方法的返回值
            线程任务没结束前是阻塞状态

    关闭线程池: shutdown()

八.lambda表达式 

    匿名内部类的简化, 在匿名内部类作为方法参数时,
    匿名内部类是实现函数式接口的时候, 可以使用lambda简化
    @FunctionalInterface: 接口中只有一个抽象方法

    普通类实现接口(可以创建无限个对象)
    匿名内部类实现接口(只有一个对象)

上一篇:实现runnable接口


下一篇:Java多线程