zoukankan      html  css  js  c++  java
  • java多线程

    第十七天知识点总结

    一、多线程

    进程:就是正在运行的程序,分配内存让应用程序能够运行。

    Windows 号称多任务(可以同时运行多个应用程序)

    宏观上看:windows确实是运行了多个程序。

    微观上看:CPU快速切换执行任务,由于速度特别快,我们人感觉不到这个切换的过程。

     

    线程:线程在一个进程中负责代码的执行,就是一个进程中的执行路径。

    疑问:没有学习线程,为什么代码可以执行。

          Java程序在运行的时候,jvm会帮我们创建一个主线程来执行代码。主线程主要负责main方法中的代码。

          一个java程序中至少有两个线程:

       一个是主线程主要负责main方法中的代码执行,一个垃圾回收器线程,负责垃圾回收。

     

    多线程:在一个进程总多个线程同时执行不同的任务。同时:单核CPU快速切换多个线程执行任务,速度特别快,人感觉不到切换

    多线程的好处:

         1.解决了进程中同时执行多个任务的问题。

         2.提高了资源的利用率

     

    多线程的弊端:

          1.增加了CPU的负担,不是线程越多越好。

          2.降低一个进程中的程序的执行效率。

          3.容易引发线程安全。

          4.出现死锁现象。

    Java中创建线程有两种方式:

    方式一:Thread(线程类)

    1.需要定义一个类来继承Thread

    2.重写Thread类中的run方法,把自定义线程的任务代码写在run方法中。每一个线程都有自己的任务代码,jvm创建的主线程的任务代码就是main方法,自定义的线程的任务代码就写在run方法中。

    3.创建thread子类,并且调用start方法来开始线程。

    注意点:一旦线程开始了,会默认执行线程对象中的run方法,但是千万不要直接调用run方法,如果直接调用了,这个run方法就饿普通方法没有区别。

    方式二:

      1.自定义一个类实现Runable接口,接口中就会提供一个run方法

      2.实现Runable接口中的run方法,将线程中的任务写在run方法中

      3.创建Runable接口的实现类对象

      4.创建一个Thread对象,并把Runable实现类创建的对象作为参数

       5.调用Thread对象的start方法开启线程

      问题:为什么要将Runable接口实现类的对象作为参数传递?

         为了让对象中的Run方法能够在线程中的Run方法中执行,就是能够将对象中的Run方法作为线程中的任务来执行。

    推荐使用:第二种创建方式

     

    线程的生命周期:

    1.new子线程类()创建线程

    2.等待运行状态(只有CPU的等待资格没有执行权)

         ↓↑

    3.运行状态(具备CPU的执行权,具备CPU的等待权)

    运行---->堵塞(线程如果执行sleep或者wait方法,那么这个时候线程会处于一个阻塞状态,如果是sleep方法,如果超过了睡眠时间,线

    程会立马进入等待运行状态,如果是wait需要通过其他线程来唤

        Sleep方法

    )------------------>等待运行状态

    4.结束

     

     

    线程中的常用方法:

     Thread(String name)   初始化线程的名字

     getName()           返回线程的名字

     setName(String name)  设置线程对象名

     Sleep()               线程睡眠指定的毫秒数

     getPriority()          返回当前线程对象的优先级 默认是5

     setPriority(int newPriority) 设置线程的优先级  虽然设置了线程的优先级,但是具体的实现取决于底层的从操作系统的实现(最大的优先级是10,最小是1,默认是5)

    currentThread()         返回CPU正在执行的线程的对象

    Java给线程加锁:

    方式一:同步代码块

    同步代码块的使用注意点:

    1.任意一个对象都可以做锁对象

    2.如果你在同步代码块中调用了sleep方法,不会释放锁对象

    3.只有真正存在线程安全的的时候才会使用同步代码块,否则会降低执行效率

    4.多线程操作锁对象必须是唯一的,否则无效

     

    不知道什么时候安全什么时候不安全?

    出现线程安全问题的根本原因:

         1.存在两个或两个以上的线程,并且线程之间共享这一个资源

         2.多个语句操作了共享资源

    方式二:同步函数用关键字synchronized修饰函数

    同步函数是否含有锁对象:有的

    同步函数的使用注意点:

       1.如果是一个非静态的函数,同步函数的锁对象就是调用方法的对象(this对象),如果是一个静态函数的锁对象是当前函数所属类的字节码文件(class对象)

       2.同步函数的锁对象固定,不能够自己来指定。

     

     

    推荐大家使用:同步代码块

      原因:1.同步代码块的锁对象可以由我任意指定,同步函数是固定的

    2.同步代码块可以可控制被同步的范围,同步函数必须是整个函数的所有代码都被同步

     

    代码同步是可以解决线程安全问题

    但是如果使用不恰当就会导致线程线程死锁问题:

    A线程等B线程完成,B线程又在等A线程 结构两个人就一直等下去,就造成了线程死锁。

     

    线程的通讯:一个线程完成自己的任务,去通知另外一个线程去完成另一个任务。

    Wait(); 等待 如果线程执行了wait方法,那么该线程就会处于一个等待状态,等待状态的线程必须要通过其他线程来调用notify()方法来唤醒。

    Notify(); 唤醒 随机唤醒一个

    notifyAll();唤醒所有等待的线程

     

    生产者和消费者。

    Waitnotify的使用注意点:

    1.wait方法和notify方法是属性Object对象

    2.Wait方法和notify方法必须在同步线程中执行

    3.Wait方法和notify方法必须由锁对象来调用

     

     

     

  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/lizixiansheng/p/6134735.html
Copyright © 2011-2022 走看看