Java多线程学习笔记

1.概念:程序:静态代码指令

      进程:代码的动态执行过程,每个进程一个方法区和堆

      线程:程序内部的一条执行路径,每一条线程各自有栈和计数器,共享堆和方法区

      单核CPU:假的多线程,执行一个挂起多个

      多核CPU:Java文件执行,main主线程、垃圾回收线程、异常处理线程同时工作

       并行:多个CPU做多个任务

       并发:一个CPU做多个任务

       单核CPU同时执行多个任务所需的时间比依次执行更慢

2.创建与使用:1.继承于Thread类的子类,重写Tread类中的run方法,创建对象于主线程,调用start方法(start方法的两个作用:启动当前线程;调用当前线程的run方法)

             2.创建一个实现了Runnable接口的类,这个类去实现Runnable中的抽象方法run(),去主程序中创建类的对象,将此对象作为参数传入Thread构造器中,创建一个Thread类的对象,通过Thread的对象调用Thread方法。(调用的是Thread类中的start,但Thread中的start调用的是Runnable中的方法,二次调用)

              3.比较:如果存在父类,或者存在共享数据,倾向于选择Runnable(但继承性,且不用加static);Thread本身重写了Runnable,自己·重写run实现二重覆盖。

        *一个线程只能start一次,解决:再new一个

        *不能直接调重写后的run方法,因为这样就不是多线程了

        *Thread类中的常用方法:start:启动;调用run

                               run:重写并声明操作

                               currentThread():静态方法,返回执行当前代码的线程

                               getName():获取当前线程的名字

                               setName():设置当前线程的名字(还可以使用构造器改名)

                               yield():释放当前CPU的执行权,但不一定会切换执行进程

                               join():在线程a中调用线程b,此时线程a进入阻塞状态,直到线程b完全执行完毕,线程才结束阻塞状态

                               sleep(long millitime):让当前线程中止指定毫秒数,在指定时间内,当前线程是阻塞状态

                              isAlive():判断当前线程是否存活(Boolean型)

        2.线程的调度:

                优先级设置从统计概率上来讲会更早执行完毕,但在实际操作中不一定发生,甚至可能相反

                 一:时间片:

                二:抢占式:高优抢低优

                            MAX, MIN,NORM(默认)

                             getPriority():获取当前线程的优先级

                             setPriority(int p):设置优先级

生命周期:JDK用Thread.State类定义了线程的状态

          新建:造完线程就是新建

          就绪:调用start就是就绪,但CPU不一定立即执行,所以不是运行

          运行:线程开始运行,失去CPU资源后再次进入就绪状态

          阻塞:sleep方法,join(),等待同步锁,wait(),suspend(),阻塞不是最终状态

          死亡:完成了使命,或者异常中断或强制中断stop

同步:线程安全问题:同步锁锁死正在执行的线程,保证没有同时参与操作,即使当前线程受阻塞也无法改变

  1. 方式:一,同步代码块synchronized

               1.     操作共享数据的代码即为需要被同步的代码

2.    共享数据:多个线程共同操作的变量。

3.    同步监视器:即锁,可以是任何一个类的对象,多线程共用一把锁(类也可以充当对象;若this指的对象唯一,也可以考虑)

弊端:速度减慢,只有一个线程执行同步代码,相当于单线程,效率减慢

      二,同步方法:如果操作共享数据的代码完整地声明在一个方法中,可以将此方法声明为同步方法       在返回值类型前面加上synchronized

      *同步方法也需要监视器,但不用显示声明,非静态为this,静态为当前的类

      *对懒汉式加以改进

            If(instance==null){

                Synchronized(类名){
                      if(instance==null){

                            Instance=new ……;

                       }

                 }

             }

             Return instance;//双重判断提高线程效率,可能在开始会有多个线程同时进入第二个判断,但后面的线程会在声明后被挡住

三.Lock锁:lock lock();lock unlock()

            *需要手动解除,但更加灵活

四.Callable接口:重写call接口,可以跟exception,但是类本身没有继承thread类,所以没有start方法,需要借助Future接口中的FutureTask

    (Future接口可以对具体的Runnable和Callable任务的执行结果进行取消、查询进程、获取结果,FutureTask是该接口唯一的实现类且实现了Runnable接口),同时还需要new一个Thread启动多线程:new Thread().start();

         *Callable相对Runnable的优势:1.call()可以有返回值

                                      2.call()可以抛出异常,被外面的操作捕获,获取异常信息

                                      3.Callable支持泛型

五.线程池:提前创建好多个线程放入线程池中,使用时直接获取,用完后放回池中,避免频繁创建和销毁,实现重复利用

    优势:提高响应速度;降低资源消耗;便于线程管理(方法在接口实现类中)

    建立:使用Executors创建ExecutorService接口实现类的对象(多态)。

                     Execute:适用于Runnable接口;submit:适用于Callable接口;shutdown:关闭线程池

  1. 死锁:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,形成线程的死锁。进入死锁状态后,不会出现异常和提示,所有线程都处于阻塞状态无法继续

*解决:专门的方法;尽量减少对同步资源的定义;尽量避免嵌套同步

通信:多个线程之间的交流(*只能在同步方法或同步代码块中使用,只有同步监视器才能调用相关关键字)

wait和notify/notifyAll:notify唤醒一个被阻塞的线程,优先唤醒优先级高的线程;wait使线程进入阻塞状态,同时释放线程握有的锁。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值