多线程简介

打印 上一主题 下一主题

主题 900|帖子 900|积分 2700

多线程简介

1.Process与Thread


  • 程序本身是指定和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。
  • 进程则是执行程序中的一次执行过程,是一个动态的概念。是系统能够资源分配的单位。
  • 通常在一个进程里,可以包含若干个线程,当然一个进程至少有一个线程,不然没有存在的意义。
  • 线程是CPU调度和执行的单位,线程是独立的执行路径
注:很多的多线程是模拟出来的,真正的多线程是指有多个cpu,即多核,如服务器。如果模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换的很快,所有就有同时执行的错觉

  • 在程序运行时,及时没有为自己创建线程,后台也会有多个线程,如主线程,gc线程等。
  • main()称为主线程,为系统的入口,用于执行整个程序
  • 在一个线程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。
  • 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制。
  • 线程会带来额外的开销,如cpu调度时间,并发控制开销
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致
  • 对现在的程序来说至少需要两个线程,一个是执行main方法的主线程,一个垃圾回收(gc)线程.
2.线程的创建

​                我们现在一共有三种方式创建线程,分别是继承Threa类,
2.1通过继承Thread类创建
  1. //创建方式一:继承Thread类,重写run()方法,调用start开启线程
  2. package com.thread;
  3. public class ThreadTest01 {
  4.     public static void main(String[] args) {
  5.         MyThread01 myThread01 = new MyThread01();
  6.         myThread01.start();
  7.         //start()方法的作用是:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码在任务完成之后,瞬间就结束了
  8.         //这段代码的任务只是为了开启一个新的栈空间,只要新的栈空间开出来,start ()方法就结束了,线程就启动成功了
  9.         //启动成功的线程会自动调用run方法,并且run方法在分支线的栈底部(压线)
  10.         //run()方法在分支栈的栈底部,man方法在主栈的栈底部,run和main是平级的
  11.         //muThread01.run;不会启动线程,不会分配新的分支线(这就是单线程)
  12.         for (int i = 0; i < 100; i++) {
  13.             System.out.println("主线程"+i);
  14.         }
  15.     }
  16.     static class MyThread01 extends Thread{
  17.         @Override
  18.         public void run() {
  19.             //编写程序,这段程序运行在分支线程中
  20.             for (int i = 0; i < 100; i++) {
  21.                 System.out.println("分支线程"+i);
  22.             }
  23.         }
  24.     }
复制代码
输出:因为输出较多,我们截取一部分,可以看出,是交替执行的。
  1. 主线程8
  2. 分支线程68
  3. 分支线程69
  4. 主线程9
  5. 分支线程70
  6. 分支线程71
  7. 分支线程72
  8. 分支线程73
  9. 分支线程74
  10. 分支线程75
  11. 分支线程76
  12. 主线程10
  13. 分支线程77
  14. 主线程11
  15. 分支线程78
  16. 主线程12
  17. 分支线程79
  18. 主线程13
  19. 分支线程80
  20. 主线程14
  21. 分支线程81
  22. 主线程15
  23. 主线程16
  24. 分支线程82
  25. 主线程17
复制代码
线程开启不一定立即执行,是由cpu安排调度的
2.2编写一个类实现java.lang.Runnable接口

代码示例:
  1. public class ThreadTest03 {
  2.     public static void main(String[] args) {
  3.         //创建线程对象
  4.         Thread t = new Thread(new MyRunnable());
  5.         //启动线程
  6.         t.start();
  7.         for (int i = 0; i < 100; i++) {
  8.             System.out.println("主线程"+i);
  9.         }
  10.     }
  11.     //这并不是一个线程类,是一个可运行的类,还不是一个线程
  12.     static class MyRunnable implements Runnable{
  13.         @Override
  14.         public void run() {
  15.             for (int i = 0; i < 100; i++) {
  16.                 System.out.println("分支线程"+i);
  17.             }
  18.         }
  19.     }
  20. }
复制代码
部分输出结果:
  1. 分支线程31
  2. 分支线程32
  3. 主线程45
  4. 主线程46
  5. 主线程47
  6. 主线程48
  7. 主线程49
  8. 主线程50
  9. 主线程51
  10. 主线程52
  11. 主线程53
  12. 主线程54
  13. 主线程55
  14. 主线程56
  15. 主线程57
  16. 主线程58
  17. 主线程59
  18. 主线程60
  19. 主线程61
  20. 分支线程33
  21. 分支线程34
  22. 分支线程35
  23. 分支线程36
  24. 分支线程37
  25. 分支线程38
  26. 分支线程39
复制代码
注:第二种方式实现接口比较常见,因为一个类实现了皆可以,还可以去继承其它的类,更加灵活!
3.多线程并发


  • 进程与进程之间的内存独立不共享
  • 在一个进程中,线程和线程的堆内存和方法区内存共享。但是栈内存独立,一个线程一个栈
假设启动十个线程,就会有十个栈空间,每个栈与每个栈之间,互不干扰,各自执行,这就是多线程并发

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表