zoukankan      html  css  js  c++  java
  • 微冷的雨之Java中的多线程初理解(一)

     

         在讲解多线程前,我们必须理解什么是多线程?而且很多人都会将进程和线程做对比。

     进程和线程

           进程:进程是操作系统结构的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。或者这样理解,进程是一块包含了某些资源的内存区域。操作系统利用进程把它的工作划分为一些功能单元。

    那么进程和程序有什么关系呢?简单的说,一个程序至少有一个进程。

         线程:是进程中某个单一顺序的控制流。也被称为轻量进程。程序执行流的最小单位。在一个程序中,这些独立运行的程序片段就叫做”线程”(Thread)。或者这样理解,线程是进程中所包含的一个或多个执行单元。进程还拥有一个私有的虚拟地址空间,该空间仅能被它所包含的线程访问。

         进程和线程的关系

       (1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

       (2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

    (3)处理机分给线程,即真正在处理机上运行的是线程。

       (4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

    多线程:就是同时有多个线程执行,共同维护程序中的数据。(个人理解)

     

    多线程实现

       那么,在Java中如何实现多线程呢??

       解析:在Java中,实现多线程有两种方式。

       方式一:用户自定义一个类,继承自Thread类,重写该类的run方法

       方式二:用户自定义一个类,实现Runnable接口,并且重写接口的run方法

       方式一用法:

       案例:我们在main方法中写一个for循环,循环1000次。并且开启一个子线程。也循环1000次。

    代码如下:

     1 public class MyThread {
     2 
     3 public static void main(String[] args) throws InterruptedException {
     4 
     5 //设置并开启多线程
     6 
     7 MyThreadTest thread=new MyThreadTest();
     8 
     9         thread.start();
    10 
    11        for (int i = 1; i <=1000; i++) {
    12 
    13          System.out.println("我是心如止水的主线程的第"+i+"次输出");
    14 
    15       }
    16 
    17 }
    18 
    19 }
    20 
    21 //俺们自己写的类:继承自Thread类
    22 
    23 class MyThreadTest extends Thread{
    24 
    25    public void run(){
    26 
    27        for (int i = 1; i <=1000; i++) {
    28 
    29          System.out.println("我是害羞的子线程A的"+i+"次输出");
    30 
    31       }
    32 
    33    }
    34 
    35 }
    36 
    37  

    方式二用法:

     1 public class MyThread {
     2 
     3     public static void main(String[] args) throws     InterruptedException {
     4 
     5     //设置并开启多线程
     6 
     7     MyThreadTestiI mi=new MyThreadTestiI();
     8 
     9     Thread thread=new  Thread(mi);
    10 
    11     thread.start();
    12 
    13     for (int i = 1; i <=1000; i++) {
    14 
    15         System.out.println("我是心如止水的主线程的第"+i+"次输出");
    16 
    17     }
    18 
    19 }
    20 
    21 }
    22 
    23  
    24 
    25 //俺们自己写的类:实现了Runnable接口
    26 
    27 class MyThreadTestiI implements Runnable{
    28 
    29       public void run(){
    30 
    31          for (int i = 1; i <=1000; i++) {
    32 
    33             System.out.println("我是害羞的子线程A的"+i+"次输出");
    34 
    35         }
    36 
    37      }
    38
    39 }
    40 
    41  

    线程休眠

     

    在程序的执行过程中,如何让程序中某个线程暂停一段时间呢?

    案例:写一个小程序,在子线程中,每循环一次,就让该线程休眠1s

     Main方法中代码如下:

     

     1 //线程休眠
     2 
     3         System.out.println("程序开始");
     4 
     5         new Thread(){
     6 
     7              public void run(){
     8 
     9                   for (int i = 1; i <=10; i++) {
    10 
    11                       //每循环一次,让程序休眠1s
    12 
    13                           try {
    14 
    15                              //这里, 必须用try,catch包裹,否则编译无法通过
    16 
    17                             //当然这里也不支持在方法上声明 throws Exception
    18 
    19                            //因为当前执行的run方法是子类的,根据异常的知识我们知道
    20  
    21                            //子类的方法的异常声明必须是父类方法异常声明的子集。但是
    22 
    23                           //我们通过查看代码可知run方法是没有进行异常声明的,所以
    24 
    25                           //这里只能采取try catch的方式。
    26 
    27                           //02。另外这里直接用的sleep,而不是 Thread.
    28 
    29                          //currentThread().sleep(millis),原因是
    30 
    31                          //sleep()方法属的类是Thread类的子类,由于Thread
    32  
    33                         //类中有sleep方法,所以在子类中可以直接使用sleep方法。
    34 
    35                          sleep(1000);
    36 
    37                         } catch (InterruptedException e) {
    38 
    39                              e.printStackTrace();
    40 
    41                          }
    42 
    43                      System.out.println("第"+i+"次循环");
    44 
    45               }
    46 
    47          }
    48 
    49         }.start();
    50 
    51  
    52 
    53  

    守护线程:

     

     1 //第一个线程
     2 
     3      Thread t1=new Thread(){
     4 
     5            public void run(){
     6 
     7                 for (int i = 1; i <=3; i++) {
     8 
     9                      System.out.println("我是第一个线程第"+i+"次循环");
    10  
    11                       try {
    12 
    13                          Thread.sleep(1000);
    14 
    15                       } catch (InterruptedException e) {
    16 
    17                           e.printStackTrace();
    18 
    19                       }
    20 
    21                }
    22 
    23            }
    24 
    25      };
    26 
    27       //第二个线程
    28 
    29      Thread t2= new Thread(){
    30 
    31           public void run(){
    32    
    33                 for (int i = 1; i <=23; i++) {
    34   
    35                      System.out.println("我是第 2 个线程第"+i+"次循环");
    36 
    37                      try {
    38 
    39                          Thread.sleep(1000);
    40 
    41                      } catch (InterruptedException e) {
    42 
    43                      e.printStackTrace();
    44 
    45                      }
    46 
    47               }
    48 
    49          }
    50 
    51       };
    52 
    53         //设置线程2为守护线程:当虚拟机发现所有的线程都为守护线程的时候,虚拟机体退出
    54 
    55         t2.setDaemon(true);
    56 
    57         t1.start();
    58 
    59         t2.start();

    好了,咱们今天的探讨到此结束!

     

  • 相关阅读:
    后台查询出来的list结果 在后台查询字典表切换 某些字段的内容
    easyui字典js 切换 jsp页面显示的内容
    easyui获取table列表中所有数据组装成json格式发送到后台
    java日常工作错误总结
    easyui模板页面 不良调查
    配置简单的拦截器java中
    读取pdf中的内容
    springMVC生成pdf文件
    C++之友元函数和友元类
    ROS初级教程 cmake cmakelist.txt 的编写教程
  • 原文地址:https://www.cnblogs.com/weilengdeyu/p/3664419.html
Copyright © 2011-2022 走看看