当前位置:   article > 正文

Java新手入门——什么是多线程_java中什么是多线程

java中什么是多线程

一、 什么是多线程:

我们现在所使用操作系统都是多任务操作系统(早期使用的DOS操作系统为单任务操作系统),多任务操作指在同一时刻可以同时做多件事(可以同时执行多个程序)。

多进程:每个程序都是一个进程,在操作系统中可以同时执行多个程序,多进程的目的是为了有效的使用CPU资源,每开一个进程系统要为该进程分配相关的系统资源(内存资源);
多线程:线程是进程内部比进程更小的执行单元(执行流|程序片段),每个线程完成一个任务,每个进程内部包含了多个线程每个线程做自己的事情,在进程中的所有线程共享该进程的资源;
主线程:在进程中至少存在一个主线程,其他子线程都由主线程开启,主线程不一定在其他线程结束后结束,有可能在其他线程结束前结束。Java中的主线程是main线程,是Java的main函数;
 

二、程序,进程,线程以及并发、并行的概念

程序:是为完成特定任务,用某种语言编写的一组指令的集合,即指一段静态的代码,静态对象。
进程:是程序的一次执行过程,或是正在运行的一个程序,是一个动态的过程,有它自身的产生,存在和消亡的过程。-------生命周期
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径

并行:多个CPU同时执行多个任务,比如:多个人同时做不同的事
并发:一个CPU(采用时间片)同时执行多个任务,比如秒杀平台,多个人做同件事

程序:静态的代码,进程:动态执行的程序,线程:进程中要同时干几件事时,每一件事的执行路径成为线程。一个程序可以有多个线程。

三、多线程的准备知识

1.线程相关API

//获取当前线程的名字
Thread.currentThread().getName()

1.start():1.启动当前线程2.调用线程中的run方法
2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
3.currentThread():静态方法,返回执行当前代码的线程
4.getName():获取当前线程的名字
5.setName():设置当前线程的名字
6.yield():主动释放当前线程的执行权
7.join():在线程中插入执行另一个线程,该线程被阻塞,直到插入执行的线程完全执行完毕以后,该线程才继续执行下去
8.stop():过时方法。当执行此方法时,强制结束当前线程。
9.sleep(long millitime):线程休眠一段时间
10.isAlive():判断当前线程是否存活
 

 2.线程的调度

调度策略:
时间片:线程的调度采用时间片轮转的方式
抢占式:高优先级的线程抢占CPU
Java的调度方法:
1.对于同优先级的线程组成先进先出队列(先到先服务),使用时间片策略
2.对高优先级,使用优先调度的抢占式策略 

3.线程的优先级 

等级:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5

方法:
getPriority():返回线程优先级
setPriority(int newPriority):改变线程的优先级

注意!高优先级的线程要抢占低优先级的线程的cpu的执行权。但是仅是从概率上来说的,高优先级的线程更有可能被执行。并不意味着只有高优先级的线程执行完以后,低优先级的线程才执行。
 

 四、创建多线程的两种常用方法

方式1:继承于Thread类 

1.创建一个集成于Thread类的子类 (通过ctrl+o(override)输入run查找run方法)
2.重写Thread类的run()方法
3.创建Thread子类的对象
4.通过此对象调用start()方法

例如多窗口售票问题:

  1. package com.example.paoduantui.Thread;
  2. import android.view.Window;
  3. /**
  4. *
  5. * 创建三个窗口卖票,总票数为100张,使用继承自Thread方式
  6. * 用静态变量保证三个线程的数据独一份
  7. *
  8. * 存在线程的安全问题,有待解决
  9. *
  10. * */
  11. public class ThreadDemo extends Thread{
  12. public static void main(String[] args){
  13. window t1 = new window();
  14. window t2 = new window();
  15. window t3 = new window();
  16. t1.setName("售票口1");
  17. t2.setName("售票口2");
  18. t3.setName("售票口3");
  19. t1.start();
  20. t2.start();
  21. t3.start();
  22. }
  23. }
  24. class window extends Thread{
  25. private static int ticket = 100; //将其加载在类的静态区,所有线程共享该静态变量
  26. @Override
  27. public void run() {
  28. while(true){
  29. if(ticket>0){
  30. // try {
  31. // sleep(100);
  32. // } catch (InterruptedException e) {
  33. // e.printStackTrace();
  34. // }
  35. System.out.println(getName()+"当前售出第"+ticket+"张票");
  36. ticket--;
  37. }else{
  38. break;
  39. }
  40. }
  41. }
  42. }

其中start与run方法的区别:
start方法的作用:1.启动当前线程 2.调用当前线程的重写的run方法(在主线程中生成子线程,有两条线程)
调用start方法以后,一条路径代表一个线程,同时执行两线程时,因为时间片的轮换,所以执行过程随机分配,且一个线程对象只能调用一次start方法。
run方法的作用:在主线程中调用以后,直接在主线程一条线程中执行了该线程中run的方法。(调用线程中的run方法,只调用run方法,并不新开线程)

总结:我们不能通过run方法来新开一个线程,只能调用线程中重写的run方法(可以在线程中不断的调用run方法,但是不能开启子线程,即不能同时干几件事),start是开启线程,再调用方法(即默认开启一次线程,调用一次run方法,可以同时执行几件事)
 

  方式2:实现Runable接口方式

1.创建一个实现了Runable接口的类
2.实现类去实现Runnable中的抽象方法:run()
3.创建实现类的对象
4.将此对象作为参数传递到Thread类中的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start() 

例如多窗口售票问题 

  1. package com.example.paoduantui.Thread;
  2. public class ThreadDemo01 {
  3. public static void main(String[] args){
  4. window1 w = new window1();
  5. //虽然有三个线程,但是只有一个窗口类实现的Runnable方法,由于三个线程共用一个window对象,所以自动共用100张票
  6. Thread t1=new Thread(w);
  7. Thread t2=new Thread(w);
  8. Thread t3=new Thread(w);
  9. t1.setName("窗口1");
  10. t2.setName("窗口2");
  11. t3.setName("窗口3");
  12. t1.start();
  13. t2.start();
  14. t3.start();
  15. }
  16. }
  17. class window1 implements Runnable{
  18. private int ticket = 100;
  19. @Override
  20. public void run() {
  21. while(true){
  22. if(ticket>0){
  23. // try {
  24. // sleep(100);
  25. // } catch (InterruptedException e) {
  26. // e.printStackTrace();
  27. // }
  28. System.out.println(Thread.currentThread().getName()+"当前售出第"+ticket+"张票");
  29. ticket--;
  30. }else{
  31. break;
  32. }
  33. }
  34. }
  35. }

 两种常用方法的比较

开发中,优先选择实现Runable接口的方式。原因如下:

区别:
1:实现的方式没有类的单继承性的局限性。
2:实现的方式更适合用来处理多个线程有共享数据的情况。
联系:
Thread也是实现自Runable,两种方式都需要重写run()方法,将线程要执行的逻辑声明在run中 。

特别声明:文章为百度等搜索各类资料所得,仅用于个人学习记录,勿赏侵删。

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号