zoukankan      html  css  js  c++  java
  • Java基础高级二(多线程)

    1.进程和线程的区别:线程是轻量级的,本省不会持太多资源,需要的时候向进程申请

    2.线程的状态:创建,可执行,执行中,等待,休眠,阻塞

    3.线程状态之间的转换

    4.线程API:Thread类,Runnable类,Object类的wait/notify方法

    5.线程同步控制:同步方法,同步代码块

    6.等待唤醒机制

    7.线程间通信

    1.进程和线程的区别

    2.线程创建方式-继承Thread

    线程创建的两种方式:

    方式一:继承Thread类

    自定义类继承Thread,并复写父类中的run(),将线程运行的方法放到run方法体重

    创建类对象的同时,线程就被创建

    调出线程的start方法,开启线程

    方式二:实现Ruunable接口

    自定义类实现Runnable接口,并覆盖接口中的run(),将线程运行的方法放到run()方法体重

    创建实现Runnable接口的子类对象,把它作为参数传递给Thread类的构造函数,创建一个Thread对象

    java可以多线程开发

    调用线程的start方法,开启线程

    两种方式的区别?

    3.线程运行的特点

    线程运行的随机性

     4.线程的生命周期

    线程是一个执行路径,调度单元

    java程序                    Thread调度

    new Thread              Runnable   可运行态

    start Thread             Runnning   运行态              Blocked/Waiting 阻塞、等待

                                   Dead

    5. 获取当前线程对象和线程名称的获取

    每个线程都有默认的名称

    按照面向对象思想,get方法getName()

    获取线程对象Thread.currentThread()

    获取线程名称demo1.getName()

     Demo demo1=new Demo("Thread-demo1");

    设置线程名称demo1.setName();

    6.线程创建方式二实现Runnable

    // 通过Thread的构造函数,传一个实现Runnable接口的对象,四个线程同享一份资源(可以把new TicketWin()对象传进来)
      Thread win1 = new Thread(new TicketWin());
      Thread win2 = new Thread(new TicketWin());
      Thread win3 = new Thread(new TicketWin());
      Thread win4 = new Thread(new TicketWin());
      // 当前对象没有start方法,Thread类里有
      win1.start();
      win2.start();
      win3.start();
      win4.start();

     7.线程两种创建方式的区别

    把不变的东西封装起来,把变的暴露出去

    把run()方法抽取出来,变成共性方法,Runnable接口是方法的声明

    自定义类实现Runnable接口,复写run()方法,实现该方法,但是这个类不是Tread类,没有其中的方法,这个类作为形参传给Thread类中

     实现Runnable接口,解决了extends Thread de 单继承的局限性,还可以进行数据资源共享

    Thread类每一个子线程都有自己的private int num这个变量

    8.线程安全问题的产生

    导致安全问题出现的原因

    1.1 多线程访问出现延迟

    1.2 线程的随机性

    通过Thread构造函数,传一个实现Runnable接口的对象,实现四个线程共享一份资源

    cpu的执行权被另一个线程抢走,另一个线程执行代码体

    多线程资源共享,可能发生的安全问题

    1.线程随机性,线程的优先级决定

    2.线程执行过程中的延迟

    9.线程安全问题的解决方案

    1.1同步(synchronized)

    代码执行完才释放cpu执行权

    10线程同步的原理

     同步的原理:锁机制,线程在执行同步代码体的时候,首先会判断同步锁,同步锁就是是否有线程正在执行

    如果这个时候,已经有一个线程进来,同步锁就相当于把同步代码块锁上,阻止其他线程

    11.线程同步的另一个体现-同步函数

    同步其实是对一段代码的封装操作
     *  函数也是对代码的一个封装
     * 
     *  同步的另一种体现形式,同步函数
     *  同步函数的体现:public synchronized void funName(){
     *  ...
     *  }
     *  同步函数的锁:
     *  this 当前对象,函数需要被对象调用

    12.同步函数使用的锁

    同步函数的锁:
     *  非静态同步函数使用的是this锁
     *  静态同步函数使用的是当前类的(TicketWin2.class)的字节码
     *  this 当前对象,函数需要被对象调用

    13.同步函数和同步代码块的选择

    同步代码块

    synchronized(锁对象){

    需要同步的代码

    }

    同步函数

    public synchronized void run(){

    执行代码

    }

    14.线程间通信示例

     同步代码块的使用是执行同步代码块的是两个线程

    多个线程间资源共享,使用同一个锁

    线程创建:参数是实现Runnable接口的子类对象

    线程同步代码块synchronized(同步锁){

    }

    15.线程间通信--等待唤醒机制

     16.线程间通信

    notify() 唤醒同一个锁等待的单个线程

    notifyAll()唤醒同一个对象监视器上等待的所有线程

    wait() 在其他线程调用此对象的notify()方法前,导致当前线程等待,是把当前线程从运行态转变成阻塞态

    17.wait()和sleep(),都让线程从运行态变为阻塞态

    wait()释放cpu执行权,释放锁

    sleep()释放cpu,不释放锁

    sleep的线程不会占用cpu,但也不释放资源

    wait() 与sleep()的区别
     * 所属类
     * 1.wait()被定义在Object类中,有函数的重载形式,可以有毫秒值,也可以没有
     *   sleep()被定义在Thread类中,并且有一个static方法,该方法必须传毫秒值
     * 2.wait()必须写在同步代码块中,必须要有锁的支持
     *   sleep()可以写在任意地方,但是具体让那个线程休眠,取决于哪个线程在执行该代码
     * 3. wait() 释放cpu执行权,其他线程还有机会抢到执行权,同时释放锁
     *   sleep() 释放了cpu的执行权,但是没有释放锁(资源)

    18.停止线程的方式

    Thread类中stop方法

    改方法已经被标注为过时的方法

    线程执行的代码结束,run()代码体结束

    线程运行代码一般都是循环,定义标记控制循环结束即可

    如果线程处于冻结状态,执行不到控制循环标记,可以使用Thread类的interrupt()方法

    19 守护线程setDeamon

    setDeamon(boolean on) 在线程开启前调用

    /*
     * 守护线程
     * 线程分两种:前台线程和后台线程
     * 线程的默认创建的时候为前台线程
     * 后台线程(守护线程或用户线程)是为前台线程服务的
     * setDeamon(true):将一个线程对象设置为后台线程
     * 前台线程结束只能通过run方法体的结束,来结束线程
     * 后台线程的生命周期依赖于前台线程,前台线程一旦结束,后台线程不管代码有没有执行结束,线程都结束
     *
     */

    20线程方法join()

    线程对象

    非静态方法

    public final void join()

    * 线程方法join()等待该线程结束
     * 线程对象调用
     * join()让当前线程执行结束,才允许其他线程抢夺cpu执行权

    21 线程方法yield

    临时暂停当前正在执行的线程对象,去执行其他线程

    Thread[Thread-1线程名称,5优先级,main线程组]----9

     静态属性 MAX_PRIORITY

                  MIN_PRIORITY

                 norm_PRIORITY 默认

    setPriority 更改线程优先级,os操作系统在进行cpu分配的时候,跟优先级有关,优先级高抢到cpu,从1到10的常量级

    22集合的线程安全问题

    当多个线程同时对list对象进行操作时

    a线程添加元素,b线程删除元素

     遇到的问题;数据错乱

    解决方法;1.自己使用同步机制控制2,把普通集合对象转换为线程安全的集合对象

    a线程遍历元素,b线程添加/删除元素

      遇到问题:同步修改一样java.util.concurrentMondilicalionException

    解决方法:1.自己使用同步机制控制2.把普通集合对象转换为线程安全的集合对象,并且遍历是还需要手动同步

    final List list = new ArrayList();
      // 线程安全的集合
      List list2 = Collections.synchronizedList(list);
      list.add("a");

    Thread athread = new Thread(new Runnable() {

       public void run() {     while (true) {      try {       Thread.sleep(10);      } catch (InterruptedException e) {       // TODO 自动生成的 catch 块       e.printStackTrace();      }      synchronized (list) {       // 遍历集合       Iterator it = list.iterator();       while (it.hasNext()) {        System.out.println(it.next() + ",");       }       System.out.println();      }

        }

       }

      }, "a");   athread.start();   // 开启第二个线程   Thread bthread = new Thread(new Runnable() {

       public void run() {     while (true) {      synchronized (list) {       list.add("k");       try {        Thread.sleep(100);       } catch (InterruptedException e) {        // TODO 自动生成的 catch 块        e.printStackTrace();       }      }

        }

       }

      }, "b");   bthread.start();

     } }

  • 相关阅读:
    Scala Partial Function从官方文档解析
    Scala Option 从官方DOC解析
    Scala Nothing 从官方DOC翻译
    从HTTP request的body中拿到JSON并反序列化为一个对象
    将一个大文件分割成若干个小文件,每个文件最多10万行
    java 可变长度参数列表
    java Class类的用法示例
    java String int转换的不同方法
    转载:大公司与小公司的比较
    java 判断5张牌的组成
  • 原文地址:https://www.cnblogs.com/shiyeyeyeye/p/5192807.html
Copyright © 2011-2022 走看看