线程之初见

作者: SongPingping | 来源:发表于2019-10-07 17:35 被阅读0次

    线程是为提升各类资源的利用率。

    创建线程几种方式

    1.通过继承Thread类(Thread本质上是对Runnable接口实现)
    2.实现Runnable接口
    3.Callable/Future带返回值的线程
    4.ThreadPool
    Thread.run重写Runnable.run,然后调用target.run()
    线程可以合理的利用多核心cpu资源,提高程序的吞吐量。

    实际应用

    new Thread()
    怎么去应用?
    文件跑批,收益文件、对账文件
    BIO模型优化
    Socket socket = Socket.accept() 阻塞,连接阻塞
    new Thread(new Handler(socket)).start(); // Handler解决r/w阻塞问题
    异步通知的优化,有些不需要立即知道请求的返回结果并且获得结果很长,如果客户端一直等待,会一直占用连接资源,还不如等有结果再通知客户端。
    责任链设计模式,责任链(如生产者,往阻塞队列添加消息)下个责任链消费消息然后生产消息传递下去。
    异步场景化放大:如kafka

    线程生命周期

    Class->start() -> ready、running->terminate
    running中,系统时间片调度,把时间片分配给别的线程,其他线程从阻塞到running
    running->sleep/join/wait/LockSupport.park->waiting
    waiting->notify/notifyall/LockSupport.unpark->running

    线程生命周期走向
    mac 终端 jps 可以看到各java进程id,通过 jstack 进程id看到运行线程堆栈日志,截图如下:
    jstack线程堆栈日志图
    模拟线程之间竞争状态代码

    线程启动方法start()?

    run()是类实例方法,调用run()不是启动一个线程
    1.下载hostpot源码

    2. vm-thread定义native方法
    start()->jvm封装各个操作系统线程方法->os::start(currentThread)->回调run()

    线程的终止?

    有两种方式
    1.线程正常运行结束
    2.线程出现异常

    Thread.currentThread().interrupt();
    //interrupt会通知线程中断,是抛出InterruptedException来终止线程
    //TODO -- 这块还是不太理解。
    

    锁 - synchronized

    线程之间出现竞争,必然会出现数据安全性问题;如资源,在单个线程是没有问题,可在多资源下就会引发数据安全性问题。
    锁的粒度越大,性能越差,锁的粒度约小,性能越好。
    实现锁的基本使用方法:
    1.修饰实例方法 - 类实例化
    2.修饰静态方法 - 类级别 - 可以跨类对象
    3.修饰代码块
    对应锁两种作用范围{1.类对象;2.实例化对象 ps区别是否跨对象跨线程被保护}-类对象生命周期控制
    锁的不同范围,代表不同的锁粒度,也说明他们的性能
    PS:2019视频(多线程的基本原理及挑战-上)22:41
    如:

    static class BlockedDemo extends Thread{
            @Override
            public void run() {
                //类对象锁,可以进行跨对象
                synchronized (BlockedDemo.class){
                    while(true){
                        try {
                            TimeUnit.SECONDS.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        
        static class BlockedDemoThis extends Thread{
            @Override
            public void run() {
                //类实例化对象,不能进行跨对象进行线程安全
                synchronized (this){
                    while(true){
                        try {
                            TimeUnit.SECONDS.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        //修改成这样就可以跨线程进行数据安全
        //static是根据类来
        static class BlockedDemoThisUpdate extends Thread{
            static Object lock = new Object();
            @Override
            public void run() {
                //类实例化对象,不能进行跨对象进行线程安全
                synchronized (lock){
                    while(true){
                        try {
                            TimeUnit.SECONDS.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    

    synchronized如何实现数据安全

    1.synchronized锁的存储


    在这里插入图片描述

    2.Markword
    无锁->{偏向锁->轻量级锁}->重量级锁(真正意义上的加锁)
    1.6之前,是基于重量级锁来实现
    既要保证数据安全,又要保证性能?
    除了基于synchroinzed的锁粒度控制之外,还能怎么办?

    相关文章

      网友评论

        本文标题:线程之初见

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