多线程简介$使用案例

 1.什么是线程? 它与进程有什么区别? 为什么要使用多线程

        1.1、线程是指程序在执行过程中, 能够执行程序代码的一个执行单元。 在 Java 语言中, 线程  有 4 种状态: 运行、 就绪、 挂起和结束
        1.2、进程是指一段正在执行的程序。 而线程有时也 被称为轻量级进程, 它是程序执行的最小单元, 一 个进程可以拥有多个线程, 各个线程之间共享程序 的内存空间 (代码段、 数据段和堆空间) 及一些进 程级的资源 (例如打开的文件), 但是各个线程拥有 自己的栈空间。

        1.3、在操作系统级别上, 程序的执行都是以进程为 单位的, 而每个进程中通常都会有多个线程互不影 响地并发执行。 多线程的使用为程序研发带来了巨大的便利:
        1) 使用多线程可以减少程序的响应时间。
        2) 与进程相比, 线程的创建和切换开销更小。
        3) 多 CPU 或多核计算机本身就具有执行多线程的能力, 如果使用单个线程, 将无法重复 利用计算机资源, 造成资源的巨大浪费。
        4) 使用多线程能简化程序的结构, 使程序便于理解和维护。

2. 多线程的创建方式

        2.1、继承Thread类,重写run()方法

                示例:                      

class MyThread1 extends Thread{
    public void run(){
        System.out.println("Thread Body");
    }
}
        2.2、实现Runnable接口,并实现该接口的run()方法  推荐使用

                示例:

class MyThread2 implements Runnable{
    @Override
    public void run() {
        System.out.println("Thread Body2");
    }
}

3. run()方法与start()方法的区别

        系统通过调用线程类的 start( )方法来启动一个线程, 此时该线程处于就绪状态, 而非运行状态, 也就意味着这个线程可以被 JVM 来调度执行。 在调度过程中, JVM 通过调用线程类的 run()方法来完成实际的操作, 当 run()方法结束后,此线程就会终止
        如果直接调用线程类的 run()方法, 这会被当作一个普通的函数调用, 程序中仍然只有主 线程这一个线程, 也就是说, start ()能够异步地调用 run( )方法, 但是直接调用 run( )方法却是同步的, 因此也就无法达到多线程的目的。
        由此可知, 只有通过调用线程类的 start( )方法才能真正达到多线程的目的。

代码示例:

/**
 * 这里要验证的是run()方法和start()方法的区别
 */

class ThreadDemo implements Runnable{
    //静态变量为所有实例所共享
    private static int i = 1;
    @Override
    public void run() {
        System.out.println(String.format("ThreadDemo%d:begin",i++));
        try{
            Thread.sleep(2000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(String.format("ThreadDemo%d:end",i));
    }
}

public class ThreadTest2 {

    public static void test1(){
        System.out.println("test1:begin");
        Thread t1=new Thread(new ThreadDemo());
        t1.start();
        System.out.println("test1:end");
    }
    public static void test2(){
        System.out.println("test2:begin");
        Thread t1=new Thread(new ThreadDemo());
        t1.run();
        System.out.println("test2:end");
    }

    public static void main(String[] args) {

        /**
         * 这里可以将test1() 分别放在try上面和try下面,分别观察结果,可以发现,在test1中的打印语句不需要等待t1.start()完成后就可以运行,
         * 也就是说,main线程与t1线程是异步执行的,而从test2可以看出
         */

        try {
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        test1();
        System.out.println();
        test2();
    }
}

运行结果:运行两次:

从这两次的运行结果可以发现,程序的运行顺序是:

mian() -->主线程阻塞5秒

test1()-->t1线程和主线程异步执行,从test1:begin test1:end 的
          结果可以看出(从侧面指出这部分也是主线程的内容) 且t1进入阻塞状态

换行

test2()-->test2中的内容依然是主线程中的,在调用sleep后主线程进入阻塞状态,
          此时t1线程接替执行,t1随后调用sleep进入阻塞状态,主线程接替,
          当主线程进行完成后,t1继续执行

  • 19
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值