Fork me on GitHub

多线程

定义

多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。

相关定义

1:并发和并行

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

在单 CPU 系统中,每一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。
在多个 CPU 系统中,则这些可以并发执行的程序便可以分配到多个处理器上(CPU),实现多任务并行执行,即利用每个处理器来处理一个可以并发执行的程序,这样多个程序便可以同时执行。目前电脑市场上说的多核CPU,便是多核处理器,核越多,并行处理的程序越多,能大大的提高电脑运行的效率。

2:线程和进程

(1):进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
角度一
一个应用程序,启动多个处理进程。换言之,所有进程隶属于当前应用程序;这是所谓的多进程服务。
角度二
启动多个同一应用程序,每个应用程序都是单进程。这个场景有些应用程序会禁用掉,有些是可以的,看应用程序的定位。如果允许,那么需要解决数据共享的问题(主要是数据写入);如果不允许,那么只能启动一个此类应用程序。
设置进程优先级
image
JAVA多进程,一般听说很少,这里不展开,以后再补充。
(2):线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程

3:线程调度
(1):分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
(2):抢占时调度: 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。

创建多线程

方法一:继承Thread类

public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                System.out.println("继承Thread类实现多线程");
            }
        }.start();
    }
//结果:
继承Thread类实现多线程

方法二:实现Runnable接口

 new  Thread(new Runnable() {
          @Override
          public void run() {
              System.out.println("实现Runnable接口,重写run方法,实现多线程");
          }
      }).start();
//结果:
实现Runnable接口,重写run方法,实现多线程

注意: 直接实现Runnable接口,没有返回值,若创建FutureTask对象:new FutureTask(Callable callable),重写Callable接口的call方法,则有返回值

方法二的优势:

1.适合多个相同的程序代码的线程去共享同一个资源。
2.可以避免java中的单继承的局限性。
3.增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
4.线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。
扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进程。

线程安全问题

定义:

当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。

解决线程安全问题方案:

方法一:

使用同步代码块

 public  void  safe(){
        //this 这里放要锁的对象,多个线程之间该对象必须一致
        synchronized (this){
            //需要同步操作的代码
            System.out.println("这是代码块锁");
        }
    }
方法二:

使用同步方法

 public synchronized void  safe(){
            //对于非static方法,同步锁就是this
            //对于static方法,我们使用当前方法所在类的字节码对象(类名.class)
            //需要同步操作的代码
            System.out.println("这是代码块锁");
    }
方法三:

Lock锁

  public void lockDemo(){
        //ReentrantLock为可重入锁
        Lock lock=new ReentrantLock();
        //加锁
        lock.lock();
        System.out.println("Lock锁示列");
        //释放锁
        lock.unlock();
    }

线程状态

定义:

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。
在API中java.lang.Thread.State这个枚举中给出了六种线程状态

状态:

六种状态:
image

posted @ 2021-04-10 13:51  晨度  阅读(58)  评论(0编辑  收藏  举报