线程——初识

大纲

在这里插入图片描述
-------------------------学前必读----------------------------------

学习不能快速成功,但一定可以快速入门
整体课程思路:
1.实践为主,理论化偏少
2.课程笔记有完整的案例和代码,(为了学习效率)再开始之前我会简单粗暴的介绍知识点案例思路,
有基础的同学听了之后可以直接结合笔记写代码,
如果没听懂再向下看视频,我会手把手编写代码和演示测试结果;
3.重要提示,学编程和学游泳一样,多实践学习效率才高,理解才透彻;
4.编码功底差的建议每个案例代码写三遍,至于为什么…<<卖油翁>>…老祖宗的智慧

-------------------------------------------------------------------------

1.线程

1.1.什么是线程

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。(来自百度百科)

一个进程可以有很多线程,每条线程并行执行不同的任务。

1.2.多线程hello word

需求:模拟在计算上一边听歌一边打游戏

三种实现方案如下:

/**
 * @author xiaomingstu
 * @date 2020-06-11 21:30
 * @description 需求分析:
 * 1.模拟一边打游戏一边听音乐,在控制台打印输出模拟
 * 2.把两个业务封装成独立的线程,实现接口Runnable或继承Thread,通过看源码你会发现Thread类实现了接口Runnable,使用本质上这两种方法时一样的。
 * 3.Thread类提供两个方法,线程主题方法run,启动线程方法start
 */
public class ThreadDemo {

    public static void main(String[] args) throws InterruptedException{

        //继承Thread
        System.out.println("-----------test start----------");
        MusicThread musicThread = new MusicThread();
        GameThread gameThread = new GameThread();
        Thread musicT1 = new Thread(musicThread);
        Thread gameT1 = new Thread(gameThread);
        musicT1.start();
        gameT1.start();
        Thread.sleep(5*1000);
        System.out.println("-----------test end----------");

        //实现Runnable
        System.out.println("-----------test start2----------");
        MusicRunnable musicRunnable = new MusicRunnable();
        GameRunnable gameRunnable = new GameRunnable();
        Thread musicT2 = new Thread(musicRunnable);
        Thread gameT2 = new Thread(gameRunnable);
        musicT2.start();
        gameT2.start();
        Thread.sleep(5*1000);
        System.out.println("-----------test end2----------");

        //简写,这种写法一般我们在做模拟测试的使用,在正式代码中建议不使用,可读性较差
        System.out.println("-----------test start3----------");
        Thread musicThread3 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println("===========海阔天空===========" + i);
            }
        });
        Thread gameThread3 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                System.out.println("==========我们一起吃鸡=========" + i);
            }
        });
        musicThread3.start();
        gameThread3.start();
        Thread.sleep(5 * 1000);
        System.out.println("-----------test end3----------");
    }
}

/**
 * 打游戏
 */
class GameRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("==========我们一起吃鸡=========" + i);
        }
    }
}


/**
 * 听音乐
 */
class MusicRunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("==========海阔天空=========" + i);
        }
    }
}


/**
 * 打游戏
 */
class GameThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println("===========我们一起农药===========" + i);
        }
    }
}


/**
 * 听音乐
 */
class MusicThread extends Thread{
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {
            System.out.println("===========海阔天空===========" + i);
        }
    }
}

总结

启动线程两种方式:

1.通过继承Thread类

2.实现Runnable接口

使用哪种方式更好?

区别:

一个类如果继承了其他类,就无法在继承Thread类,在Java中,一个类只能继承一个类,而一个类如果实现了一个接口,还可以实现其他接口,接口是可以多实现的,所以说Runable的扩展性更强,但是继承的方式更简单,个人建议一般情况下使用Thread;

实现接口Runnable或继承Thread,通过看源码你会发现Thread类实现了接口Runnable,使用本质上这两种方法是一样的

启动线程流程:

创建启动线程的方式一:继承Thread类

   1.将业务方法封装成线程对象,自定义类t extends Thread类; 

   2.覆写run方法: 覆写第一步中的run方法;

   3.创建自定义对象t

   4.启动线程 t.start();

创建启动线程方式二:实现Runnable接口

  1.将业务方法封装成线程对象,自定义类t implements Runnable接口;

  2.实现第一步中的run方法

  3.创建自定义对象t

  4.启动线程 new Thread(t).start();
1.3.对主线程与创建线程执行顺序的理解

问题:
直接写一个简单的HelloWorld 程序,有没有线程?
==>有一个主线程,在垃圾回收的时候,有gc 线程。

/**
 * @author xiaomingstu
 * @date 2020-06-11 21:49
 * 问题:
 * 直接写一个简单的HelloWorld 程序,有没有线程?
 * ==>有一个主线程,在垃圾回收的时候,有gc 线程。
 * 结论:一旦线程启动起来之后就是独立的,和创建环境没有关系;
 * 启动线程不能直接调用run方法,必须调用start方法;
 */
public class ThreadDemo1 {

    public static void main(String[] args) throws InterruptedException{

        /**
         * 如果把创建线程放在循环语句的 下 面,会交替出现吗
         * ==>否,因为主线程执行完成后才会启动hello线程
         */
        System.out.println("-------------test start--------------");
        //执行主线程
        for (int i = 0; i < 100; i++) {
            System.out.println("----------------test1------------");
        }
        // 启动hello线程
        new HelloThread().start();
        Thread.sleep(5 * 1000);
        System.out.println("-------------test end--------------");


        /**
         * 如果把创建线程放在循环语句的上面,会交替出现吗
         * ==>可能会,可能不会,可能出现for循环完之后,线程还没有启动完;
         */
        System.out.println("-------------test start2--------------");
        // 启动hello线程
        new HelloThread().start();
        //执行主线程
        for (int i = 0; i < 100; i++) {
            System.out.println("----------------test2------------");
        }
        Thread.sleep(5 * 1000);
        System.out.println("-------------test end2--------------");
    }
}

class HelloThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("----------------HelloThread----------------");
        }
    }
}

结论:一旦线程启动起来之后就是独立的,和创建环境没有关系;
启动线程不能直接调用run方法,必须调用start方法;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值