zoukankan      html  css  js  c++  java
  • java实现多线程(上)

    一、三个基本概念:程序、进程、线程

      程序:是为了完成特定的任务、用某种语言所编写的一组语言的集合。即指一段静态的代码。

      进程:是程序的一次执行过程,或是正在运行的程序。是一个动态的过程:有它自身的产生、存在和消亡过程。

        >进程作为资源分配的单位,系统在巡行时会为每个进程分配不同的内存区域。

      线程:进程可以进一步细化为线程,是一个程序内部的一条执行路径。

        >若一个进程同一时间并行的执行多个线程,就是支持多线程。

        >线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc)。线程的切换开销小。

        >一个进程的多个线程可以共享资源,这使得线程间的通讯更加便捷高效,但是同样的带来了安全隐患。

    二、单核CPU和多核CPU的理解:

    单核CPU:其实是一种假的多线程,因为在一个时间单元内,只能执行一个线程的任务。但是由于CPU时间单元特别短,感觉就好像是同时在做一样。

    多核CPU:多核才是正在的多线程,能更好的发挥多线程的效率,一个java应用程序java.exe其实至少有三个线程:main()主线程、gc()垃圾回收线程、异常处理线程。异常发生,会影响主线程。

    三、并发和并行:

    并行:多个CPU同时执行多个任务。多个人做不同事。

    并发:一个CPU同时执行多个任务。比如:秒杀、多个人做一件事。

    四、多线程的创建:

    方式一:继承于Thread类

    1.创建一个继承于Thread类的子类

    2.重写Thread类的run()——>将此线程执行的操作放到run()中

    3.创建Thread类的子类的对象

    4.通过此对象调用start()

    例如:遍历100以内的所有偶数:

    class example extends Thread{
    @override
    public void run(){
    forint i = 0;i<100;i++){
      if(i %2 == 0){
    System.out.print(i);
    }}}}
    public class exampletest{
    public static void main(String【】args){
    
    example ex = new example();//每创建一个对象,就可以创建一个线程的调用
    
    ex.start();//启动当前线程,调用当前线程的run()方法
    System.out.print("hello");
    }
    }

    这个时候main线程下的打印“hello”和start方法的遍历就是分开进行的。

    方式二:实现Runnable接口

    1.创建一个实现了Runnable接口的类

    2.实现类去实现Runnable中的抽象方法:run()

    3.创建实现类的对象

    4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象

    5.通过Thread类的对象调用start()

    class example implements Runnable{
    @override
    public void run(){
    forint i = 0;i<100;i++){
      if(i %2 == 0){
    System.out.print(i);
    }}}}
    public class exampletest1{
    public static void main(String【】args){
    
    example ex = new example();//创建实现类的对象
    Thread th = new Thread(ex);//将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
    
    th.start();//启动当前线程,调用当前线程的run()方法(通过查看源码,其实这个run()调用的是Runnable类型的target,而这个就是作为实参传递的实现类对象!)
    System.out.print("hello");
    }

    比较以上两种创建线程的方式:

    开发中:优先选择实现Runnable接口的方式

    原因:1.实现的方式没有类的单继承性的局限性

       2.实现的方式更适合来处理多个线程有共享数据的情况。

    联系:public class Thread implements Runnable(其实都是Runnable中的run())

    相同点:两种方式都要重写run(),将线程要执行的逻辑声明在run()中。

    五、Thread类的有关方法:

    void start:启动线程,并执行对象的run()方法

    run():线程在被调用时执行的操作

    String getName():返回线程的名称

    void steName(String name):设置该线程名称

    static Thread currentThread():返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类。

    static void yield():线程让步

      >暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程(注意:暂停执行的线程,在抢占的时候仍然有机会抢到资源执行)

      >若队列中没有同优先级的线程,忽略此方法。

    join():当某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到join()方法加入的join线程执行完为止。

      >低优先级的线程也可以获得执行

    static void sleep(long millis):(时间单位:毫秒)

      >令当前活动线程在指定时间段内放弃对CPU的控制,使其他线程有机会被执行,时间到后重新排队。

      >抛出InterruptedException异常。

    stop():强制线程生命期结束,不推荐使用(过时了)

    boolean isAlive():判断线程是否还活着。

    六、线程的调度:

    java的调度方法:

      >同优先级线程组成先进先出(先到先服务),使用时间片策略

      >对高优先级,使用优先调度的抢占式策略

    线程的优先级等级:

      >MAX_PRIORITY: 10

      >MIN_PRIORITY: 1

      >NORM_PRIORITY: 5

    涉及的方法:

      >getPriority():返回线程优先值

      >setPriority(int newPriority):改变线程的优先级

    说明:

      >线程创建时继承父线程的优先级

      >低优先级只是获得调用的概率低,并非一定是在高优先级线程之后才被调用

  • 相关阅读:
    Spring Boot面试题(转至)
    深入理解Java输入输出流
    java基础 第十六章(连接数据库)
    java基础 第十五章(数据库)
    java基础 第十四章(Servlet声明周期、Servlet向jsp中提供数据、Servlet跳转jsp、jsp中书写java代码)
    java基础 第十三章(HashMap、Servlet介绍)
    java基础 第十二章(异常处理、工具类、集合)
    java基础 第十一章(多态、抽象类、接口、包装类、String)
    java基础 第十章(this,继承,重写和重载的区别)
    java基础 第九章(设计模式 单例模式)
  • 原文地址:https://www.cnblogs.com/liuhuan425/p/10835751.html
Copyright © 2011-2022 走看看