微冷的雨之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();

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

 

原文地址:https://www.cnblogs.com/weilengdeyu/p/3664419.html