17.多线程(1)

1.进程定义

      在操作系统中运行的某个软件或者某个程序。

      任何软件或者程序要运行都要被加载到内存中,而内存负责运行这个软件或程序所需要的那些内存空间,就被称为当前软件在内存中的一个进程。

      进程需要依赖于操作系统,是在操作系统中动态运行的静态代码。

2.线程定义

      线程就是在操作系统中动态运行的静态代码【进程】中的某一项具体功能的执行过程【执行轨迹/执行线索】。

      比如我们在window操作系统上打开“暴风影音”播放电影,此时“暴风影音”就会在window操作系统中产生一个进程;打开“暴风影音”播放电影的时候有画面,声音,中文字幕等等,这些画面,声音,中文字幕就是这个“暴风影音”进程中的多个线程。

3.多线程定义

        某一个程序在运行的时候可能会产生多个不同的执行线索【执行轨迹】,这些多个不同的执行线索【执行轨迹】共同运行的情况就是多线程。

      往往我们会感觉到这些多个不同的执行线索【执行轨迹】同时执行,实际上这时一种错觉假象,实际上当这些多个不同的执行线索【执行轨迹】在运行的时候,某一个时刻只有一个执行线索【执行轨迹】在运行,只是这多个不同的执行线索【执行轨迹】快速的切换而已。

4.多线程作用

      (1)使用多线程的目的就是为了提高程序的执行效率。

      (2)解决并发问题。

并行和并发区别

并行

多个处理器或多核处理器同时处理多个任务

并发

多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行

5.多线程的创建方式【4种】

5.1通过继承Thread类创建线程类

5.1.1 创建步骤

        1.创建一个类,继承Thread类;

        2.重写run方法;

        3.将需要由线程执行的具体动作写入run方法

例:

public class MyThread extends Thread{

   public void run() {

      for(int i=1;i<=50;i++){

          //得到当前正在运行的线程对象的名称

           String name = Thread.currentThread().getName();

           System.out.println(name+"---i=="+i);

      }

   }

}

5.1.2 运行步骤

      1.创建线程类的对象;

        2.通过线程对象调用start方法启动线程

              start方法只负责启动线程,启动后具体运行怎么走由操作系统决定。

例:

public class MyThreadMain {



   public static void main(String[] args) {

      //创建线程类的对象

      MyThread mythread1=new MyThread();//线程1

      MyThread mythread2=new MyThread();//线程2

      //通过线程对象调用start方法启动线程

      mythread1.start();

      mythread2.start();

   }

}

 

每次运行的结果是不一样的。

5.2 通过实现Runnable接口创建线程类

        Runnable接口--Thread类就实现过这个接口

        Runnable接口里只有一个run方法。

5.2.1 创建步骤

        1.创建一个类,实现Runnable接口;

        2.重写run方法;

        3.将需要由线程执行的具体动作写入run方法。

例:

public class MyThread implements Runnable{



   public void run() {

      for(int i=1;i<=10;i++){

          //得到当前正在运行的线程对象的名称

           String name = Thread.currentThread().getName();

           System.out.println(name+"---i=="+i);

      }

   }

}

5.2.2 运行步骤

        1.创建目标对象

        2.通过Thread类的构造方法创建线程对象

        3.通过线程对象调用start方法启动线程

例:

public class MyThreadMain {



   public static void main(String[] args) {

      //启动线程要用start方法,而start方法是Thread类的方法,Runnable接口里面没有

      //Runnable接口只有一个run方法

      //因此直接new MyThread 是调用不了start方法的

      //所以需要用到Thread类的构造方法public Thread(Runnable target)

      //当一个方法的参数是接口类型的时候,可以传递子类对象,因此把MyThread对象传进去

      MyThread myThread = new MyThread();//创建目标对象

      Thread th1=new Thread(myThread);//创建线程对象

      Thread th2=new Thread(myThread);

      th1.start();

      th2.start();



   }

}

5.3 通过Callable和Future接口创建线程

        java.util.concurrent.Callable接口--这个接口中只有一个方法call();

        java.util.concurrent.Future接口--有一个重要方法get() ;

              1. public boolean cancel(boolean mayInterruptIfRunning)是否取消正在执行的线程任务【false为取消任务】

              2. public boolean isCancelled()判断是否是线程任务没有运行结束之前取消线程

              3. public boolean isDone()判断线程任务是否正常执行完毕

              4. V get()得到线程任务的执行结果

        java.util.concurrent.FutureTask--继承了Runnable接口。

              1. public boolean cancel(boolean mayInterruptIfRunning)是否取消正在执行的线程任务【false为取消任务】

              2. public boolean isCancelled()判断是否是线程任务没有运行结束之前取消线程

              3. public boolean isDone()判断线程任务是否正常执行完毕

              4. V get()得到线程任务的执行结果

        Future接口和FutureTask类都有上面四个方法,因为FutureTask实现了RunnableFuture,RunnableFuture继承了Runnable, Future。

5.1.1 创建步骤

        1.创建一个类,实现Callable接口

        2.重写call();

        3.将需要由线程执行的具体动作写入call()方法

        注意:实现Callable接口的时候需要指定线程执行结果的返回值类型

例:

import java.util.concurrent.Callable;

//创建一个类,实现Callable接口,<>返回值

public class MyThread implements Callable<Integer>{



   public Integer call() throws Exception {

      int i=1;

      while(i<=10){

          String name=Thread.currentThread().getName();

          System.out.println(name+"----i=="+i);

          i++;

      }

      return i;

   }

}

5.1.2 运行步骤

           1.创建目标对象

        2.通过FutureTask类的构造方法public FutureTask(Callable<V> callable)封装目标对象成Runnable子类对象

        3.通过Thread类的构造方法public Thread(Runnable runnable)创建线程对象

例:

import java.util.concurrent.FutureTask;



public class MyThreadMain {



   public static void main(String[] args) {

      //创建目标对象

      MyThread myThread = new MyThread();

      //通过FutureTask类的构造方法public FutureTask(Callable<V> callable)封装目标对象成Runnable子类对象

      FutureTask futuretask1=new FutureTask(myThread);

      FutureTask futuretask2=new FutureTask(myThread);

      //通过Thread类的构造方法public Thread(Runnable runnable)创建线程对象

       Thread thread1=new Thread(futuretask1);

       Thread thread2=new Thread(futuretask2);

      //启动线程

       thread1.start();

       thread2.start();

   }

}

5.4 通过线程池创建多线程

       使用的比较少,里面的东西有些还没学到,暂时不处理学习。

6.多线程创建方式的区别***

继承Thread类

实现Runnable接口

Callable和Future接口

创建新类继承Thread类重写run方法

创建新类实现Runnable接口重写run方法

创建新类实现Callable接口重写call方法,注意Callable接口的泛型类型

run 方法没有返回值,没有声明抛出异常

call方法有返回值,通过Future接口提供的get方法得到返回值,可以声明抛出异常

创建Thread类的子类对象【线程对象】,通过子类对象调用start方法启动线程

创建实现Runnable接口的子类对象【目标对象】,通过Thread类的构造方法传递参数,关联目标对象,创建线程对象【Thread类的对象】,通过线程对象调用start方法启动线程

创建实现Callable接口的子类对象【目标对象】,通过Future接口的子类FutureTask将目标对象包装成Runnable接口的子类对象,通过Thread类的构造方法,关联包装后的Runnable接口的子类对象,创建Thread类对象【线程对象】,通过线程对象调用start方法启动线程

无法资源共享

可以资源共享

可以资源共享

不考虑资源共享时采用

考虑资源共享时采用

考虑资源共享时采用

资源共享意思是不共用一个目标对象,比如卖5张票,线程1和2都会取卖着5张票,但没有共用5,导致线程1买了5张,线程2卖了5张,最后成了卖出10张票。

例:

public class MyThread extends Thread {

   private int piao = 5;



   public void run() {

      boolean flag=true;

      while(flag){

          if(piao<=0){

             flag=false;

          }else{

             String name=Thread.currentThread().getName();

          System.out.println(name+",卖出1张票,还剩"+(--piao)+"票");

          }

      }

   } 

}

public class MyThreadMain {

   public static void main(String[] args) {

      //创建线程类的对象

      MyThread mythread1=new MyThread();//线程1

      MyThread mythread2=new MyThread();//线程2

      //通过线程对象调用start方法启动线程

      mythread1.start();

      mythread2.start();

   }

}

 

此处涉及线程同步问题,下一个文章再说

使用实现Runnable接口方法会资源共享

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java-请多指教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值