• 多线程——线程的创建以及操作线程的相关方法简介


    一、概念:

    1、进程:

    进程是程序的一次动态执行过程。用进程来对应一个程序,每个进程对应一定的内存地址空间,并且只能使用它自己的内存空间,各个进程间互不干扰。

    2、线程:

    线程是程序内部的控制流,比进程更小的执行单位,是进程内部的子任务。一个进程在执行过程中,为了同时完成多个操作,可以产生多个线程,形成多条执行线索。

    3、进程与线程的区别:

       (1)、每个进程有一段专有内存空间。进程各自占有不同空间,内存消耗很大,会造成系统在不同程序之间切换时开销很大,进程之间通信速度很慢

       (2)、同一进程的各线程之间共享相同内存空间,利用共享内存来实现数据交换、实时通信及必要的同步工作。线程之间通信速度快,相互切换所占系统资源也小

    二、创建线程的2种方式

    在Java中,线程的创建一般有2种方式:1.继承Thread类 ;2.实现Runnable接口。

    方式一:继承Thread类

    示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    package com.model.elgin.thread;

    public class TestThread1 {
       
       
    public static void main(String[] args) {
             MyThread mt1=
    new MyThread();
             MyThread mt2=
    new MyThread();
            
    //setName方法为线程命名
             mt1.setName("mt1");
             mt2.setName(
    "mt2");;
            
    //start方法开启线程
             mt1.start();
             mt2.start();
        }
            
    }
        
    class MyThreadextends Thread{
        
        @Override
       
    public void run() {
           
    for (int i =0; i < 10; i++) {
               
    //currentThread()为Thread类的静态方法,作用是得到当前正在运行的线程 
                System.out.println(Thread.currentThread().getName() +": Hello thread-" + i);
            }
        }   
    }

    运行结果:

    image

    从上面的运行结果可以看出:2个线程在同时运行,争夺CPU资源,并没有先后的优先级,如果再次运行一次,那么会得到不同的顺序结果。

    方式二:实现Runnable接口

    示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    package com.model.elgin.thread;

    public class TestThread2 {
       
    public static void main(String[] args) {
           
    //声明一个资源类实例
            RunThread rt=new RunThread();
           
    //将此实例传入Thread构造方法,创建线程对象
            Thread rmt1=new Thread(rt);
            rmt1.setName(
    "rmt1");
            Thread rmt2=
    new Thread(rt);
            rmt2.setName(
    "rmt2");
            rmt1.start();
            rmt2.start();
        }
    }

    //声明资源类,需要实现Runnable接口,用来创建线程
    class RunThreadimplements Runnable{
        @Override
       
    public void run() {
           
    for (int i =0; i < 10; i++) {
               
    //currentThread()为Thread类的静态方法,作用是得到当前正在运行的线程 
                System.out.println(Thread.currentThread().getName() +": Hello thread-" + i);
            }   
        }
    }

    注意,这种方式必须将Runnable作为Thread类的参数,然后通过Thread的start方法来创建一个新线程来执行该子任务。

    如果直接调用Runnable的run方法的话,是不会创建新线程的,这跟普通的方法调用没有任何区别。

    事实上,查看Thread类的实现源代码会发现Thread类是实现了Runnable接口的。

    小结:

    在Java中是不支持多继承的,如果一个类已经继承了另一个类,那么它就不能通过继承Thread类来实现多线程操作,这时候就可以使用第二种方式,也就是实现Runable接口来实现。因为Java是单继承,多实现的。另一个方面说,如果一个类已经继承Thread了,那么它就无法继承其他类去实现更复杂的功能,所以多线程的实现推荐使用实现Runable接口的方式。

    三 、Thread类中控制线程的重要方法:

    #上面2个例子中已使用过

    public static native Thread currentThread() 返回当前活动线程的引用;

    public static native void yield() 使当前执行线程暂时停止执行而让其他线程执行;

    示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    package com.model.elgin.thread;

    public class TestThread1 {
       
       
    public static void main(String[] args)  {
             MyThread mt1=
    new MyThread();
             MyThread1 mt2=
    new MyThread1();
            
    //setName方法为线程命名
             mt1.setName("mt1");
             mt2.setName(
    "mt2");;
            
    //start方法开启线程
             mt1.start(); 
             mt2.start();
        }
            
    }
        
    class MyThreadextends Thread{
        
        @Override
       
    public void run() {
           
    for (int i =0; i < 10; i++) {
               
    //currentThread()为Thread类的静态方法,作用是得到当前正在运行的线程 
                System.out.println(Thread.currentThread().getName() +": Hello thread1-" + i);
            }
        }   
    }

    class MyThread1extends Thread{
        
        @Override
       
    public void run() {
           
    //调用yield方法使当前线程暂停等其它线程执行完毕之后再执行它
            //Thread.yield();
            for (int i =0; i < 10; i++) {
               
    //currentThread()为Thread类的静态方法,作用是得到当前正在运行的线程 
                System.out.println(Thread.currentThread().getName() +": Hello thread2-" + i);
            }
        }   
    }

    结果对比:

    左边为未打开34行注释的结果(即未调用yield方法),右边是调用yield的结果

    imageimage

    public static native void sleep(long millis) throws InterruptedException 使当前活动线程睡眠指定的时间millisme;

    public static void sleep(long millis,int nanos)throws InterruptedException 使当前活动线程睡眠指定的时间millisme加上十万分之nanos秒;

    public native synchronized void start() 开始运行当前线程;

    public void run() 该方法用来定义线程体。一旦线程被启动执行,就开始执行这个方法;

    public final native boolean isAlive() 测试当前线程是否在活动;

    #---------@Deprecated注解方法开始,不鼓励使用-----------#

    public final void stop() 强制当前线程停止运行,并抛出ThreadDead错误;

    public void destroy() 撤消当前线程;

    public final void suspend() 临时挂起当前线程;

    public final void resume() 恢复运行挂起的线程;

    #---------@Deprecated注解方法结束,不鼓励使用-----------#

    public final void setPriority(int newPriouity) 设置线程的优先级

    可以在MIN_PRIORITY、NORM_PRIORIITY和MAX_PRIORITY之间,一般MIN_PRIORITY为1,MAX_PRIORITY为10;

    public final int getPriority() 获得当前线程的优先级;

    public final void setName(String name) 设置线程名;

    public final String getName() 得到当前线程名;

    public final ThreadGroup getThreadGroup( ) 返回当前的线程组;

    小结:

    Thread提供的控制线程的主要方法:

    • 启动和停止:start(), stop()
    • 等待和通知: wait(), notify()
    • 睡眠: sleep()
    • 挂起和恢复: suspend(), resume()
    • 撤消线程:destroy()
    • join()
    • yield()
    • isAlive()
    • setPriority()

    后续将结合线程的生命周期来介绍上述的几个重点方法

  • 相关阅读:
    添加GDataXMLNODE.h和.m的方法
    NSPredicate的用法
    oc正则表达式基本语法(二)
    洛谷3931 [洛谷八连测] 一道难题
    洛谷2024 食物链 并查集
    洛谷1005 【NOIP2007】矩阵取数游戏
    洛谷3927 [洛谷八连测] 一道中档题
    洛谷1113 杂务
    洛谷1019 单词接龙 字符串dfs
    洛谷1414 又是毕业季II
  • 原文地址:https://www.cnblogs.com/elgin-seth/p/5293719.html
Copyright © 2020-2023  润新知