JAVA基础【多线程】史上最简单基础入门01

前言:

在介绍多线程之前,先给大家普及下什么是进程,什么是线程。以及我们生活当中使用的那些软件使用到了多线程。

本文主线:

本文 从什么是进程,什么是线程。以及生活当中的多线程应用,前面的这些作为后面讲解什么是多线程的铺垫。主要介绍基本的并发,并行。以及如何创建多线程。

目录

基础铺垫

什么是 进程,线程?

生活中用到的多线程软件

间接入门

并发与并行

创建线程

Theard

Runable

Theard和.Runnable的区别

入门完毕

买票案例

结果:


 

基础铺垫

什么是 进程,线程?

进程

是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多 个进程;

进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创 建、运行到消亡的过程。

线程

线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。

一个进程 中是可以有多个线程的,这个应用程序也可以称之为多线程程序。

简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

生活中用到的多线程软件

以联想电脑管家为例,左边每一个功能都是一个单独的线程。也就是每个功能直接的运行时独立的,互不影响。

在运行加速清理的时候,仍然可以去进行杀毒。

间接入门

简介:

上面介绍了什么是进程,什么是线程。以及在生活当中使用的多线程软件。下面开始进入今天的主题 “多线程”

并发与并行

并发:指两个或多个事件在同一个时间段内发生。

并行:指两个或多个事件在同一时刻发生(同时发生)。

 

创建线程

    创建线程有两种方式,一种直接继承Thread类。还有一种实现.Runnable接口。

不过.Runnable接口只有一个run方法,没有开始方法。还得借助Thread类的Start方法执行,直接把.Runnable的实现对象传到Thread的构造函数里。

Theard

package itheima.demo01.getName;
/*
* 线程名称:
* 主线程:main
* 新线程:Thread-0,Thread-1
* */
public class Demo01GetThreadName {
    public static void main(String[] args) {
        //创建Thread类的子类对象
        MyThread mt=new MyThread();
        //给线程设置名称
        mt.setName("kang");
        //调用start方法,开启新线程,执行run方法
        mt.start();
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new  MyThread().start();
        new  MyThread().start();
        //视频进度:threadl类的常用方法,开头
    }
}

  myTheard类

package itheima.demo01.getName;
/*
* 获取线程的名称
*  1.使用Thread类中的方法getName()
*  String getName()
*  返回该线程的名称。
*  2.可以先获取当前正在执行的线程,使用线程的方法geName()获取线程名称
*  static Thread currenThread();
* */
//定义为Thread类的子类
public class MyThread  extends Thread{
    //重写Thread类中的run方法,设置线程
    @Override
    public void run() {
        //获取线程名称
        System.out.println(currentThread());
//        String name = getName();
//        System.out.println(name);
    }
}

Runable

这个和下面的买票案例一样(同一个案例),就是这个没有做线程安全。这个会出现两个线程买同一张票,或者出现不存在的票比如-1 (具体请看下面结果)

package itheima.demo06.ThreadSafe;
/*
* 模拟买票案例
* 创建三个线程,同时开启,对共享的票进行出售
*
* */
public class Demo01Ticket {
    public static void main(String[] args) {
        //实例化接口实现类
        RunnableImpl ticket0=new RunnableImpl();
        //实例化Thread类,把接口类对象传进构造参数里
        Thread th=new Thread(ticket0);
        Thread th1=new Thread(ticket0);
        Thread th2=new Thread(ticket0);
        //开启线程
        th.start();
        th1.start();
        th2.start();


    }
}

 买票Runable接口实现类

package itheima.demo06.ThreadSafe;
/*
* 实现Runable接口:实现买票案例
* */
public class RunnableImpl implements Runnable {
    //定义一个多线程共享的票源
    private int ticket=100;
    @Override
    public void run() {
        //使用死循环,让买票操作重复执行
        while (true){
            //判断是否有票
            if(ticket>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //票存在,买票ticker...
                System.out.println(Thread.currentThread().getName()+"----->正在买票"+ticket+"张票");
                ticket--;
            }
        }
    }
}

结果:

Theard和.Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

总结:

实现Runnable接口比继承Thread类所具有的优势:

1. 适合多个相同的程序代码的线程去共享同一个资源。

2. 可以避免java中的单继承的局限性。

3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

入门完毕

买票案例

package itheima.demo07.Synchranized;

/*
* 模拟买票案例
* 创建三个线程,同时开启,对共享的票进行出售
*
* */
public class Demo01Ticket {
    public static void main(String[] args) {
        //实例化接口实现类
        RunnableImpl ticket0=new RunnableImpl();
        //实例化Thread类,把接口类对象传进构造参数里
        Thread th=new Thread(ticket0);
        Thread th1=new Thread(ticket0);
        Thread th2=new Thread(ticket0);
        //开启线程
        th.start();
        th1.start();
        th2.start();
  

    }
}

 买票Runable接口实现类

package itheima.demo07.Synchranized;
/*
* 实现Runable接口:实现买票案例
* 第一种锁解决方案
* */
public class RunnableImpl implements Runnable {
    //定义一个多线程共享的票源
    private int ticket=100;
    //创建一个锁对象
    Object obj=new Object();
    @Override
    public void run() {
        //使用死循环,让买票操作重复执行
        while (true){
            //同步代码块
            synchronized (obj){
                //判断是否有票
                if(ticket>0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //票存在,买票ticker...
                    System.out.println(Thread.currentThread().getName()+"----->正在买票"+ticket+"张票");
                    ticket--;
                }
            }
        }
    }
}

结果:

这个案例使用到了同步代码块,也就是synchronized线程同步的概念。(线程同步的三种用法,下一篇博客介绍。)

posted @ 2020-12-09 17:28  康世行  阅读(23)  评论(0编辑  收藏  举报