多线程学习

多线程学习

1、线程概述

  进程:运行在自己的地址空间之内的自包容的程序,是一个动态执行的过程。比如我打开记事本写一个.txt文件这个过程是一个进程;打开eclipse写一个程序这个过程是一个进程;运行这个程序也是一个进程;人跑50m短跑这个过程也可以说是一个进程。

  线程:是比进程更小的执行单位,是一个个独立的子任务,一个线程就是在进程中的一个的单一的顺序控制流。比如运行一个.java文件时,主线程就是立刻启动运行;50m短跑的一个同学是一个线程;比赛100m x 4 这个过程是一个进程,这个进程给参赛的4位同学都分配了任务(每位同学跑100m)。

  从上我们可以看到进程之间相互隔开,互不影响,彼此不干涉的;而同一个进程之间的线程之间时共享资源的(接力赛的接力棒),线程之间的执行顺序也是不确定的,在这个100 x 4 比赛中,每个同学跑第几棒是不确定的,顺序是由leader(这里我们假设是班主任)来确定的,此时班主任担任的就是一个CPU在分配资源的角色。

  多线程:顾名思义就是一个进程中有多个线程。java的线程机制是抢占式,这表示调度机制会周期性地中断线程,讲上下文切换到另一个线程,从而为每个线程都提供时间片,使得每个线程都分配到数量合理的事件驱动它的任务。

  注意:多线程是不能提高运行效率的,相反的在单处理器上还会降低一些运行效率,因为相对于所有部分顺序执行,多线程增加了上下文切换的代价(从一个任务到另一个任务),但是从程序设计、资源平衡、用户使用便捷等来看,多线程是很有必要的。

2、线程实现方法

  1. 实现Runnable接口,实现run()方法
class mythread implements Runnable{
   public void run( ) {/* 实现该方法*/ }
 }
  1. 继承Thread类,重写run()方法
class mythread extends Thread {
   public void run( ) {/* 重写该方法*/ }
  }

3、线程的重要方法

常用的方法:

  • start():继承Thread类时,调用Thread对象的start()方法为线程执行必要的初始化操作,启动线程,然后调用Runnable的run()方法运行线程。
  • sleep(time):用于将线程挂起,线程休眠time毫秒。
  • wait():中途释放锁,出来等候,但不重新排队。
  • notify():与wait配套使用,通知wait()进程中心排队,排队顺序不确定,取决于JVM。
  • notifyAll():通知所有wait()线程重新排队。
  • yield():暂停目前正在执行的线程,切换其他的线程。

5、代码实现多线程

1. 线程可以驱动任务,实现多线程的方法之一就是声明一个实现 Runnable 接口的类,并实现 run() 方法

 1 package a20190424;
 2 import java.util.*;
 3 
 4 public class Liftoff implements Runnable {
 5     //@Override
 6     
 7     protected int countDown = 10;
 8     private static int taskCount = 0;
 9     private final int id = taskCount++; //使用Final关键字,id的值不可更改
10     public Liftoff() {}
11     public Liftoff(int countDown)
12     {
13         this.countDown = countDown;
14     }
15     public String status() {
16         return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff ! " ) + "), ";
17     }
18     public void run() {
19         // TODO Auto-generated method stub
20         while(countDown -- > 0)
21         {
22             System.out.print(status());
23             Thread.yield();
24         }
25 
26     }
27 
28 }
29 
30 
31 
32 package a20190424;
33 
34 public class LiftMain {
35     public static void main(String[] args) {
36         Liftoff lift = new Liftoff();
37         lift.run();
38     }
39 
40 }
View Code

输出结果

#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff ! ), 

2.Thread类,将Runnable对象转成工作任务的传统方式将其提交给Thread构造器

 1 package a20190424;
 2 import java.util.*;
 3 
 4 public class Liftoff implements Runnable {
 5     //@Override
 6     
 7     protected int countDown = 10;
 8     private static int taskCount = 0;
 9     private final int id = taskCount++; //使用Final关键字,id的值不可更改
10     public Liftoff() {}
11     public Liftoff(int countDown)
12     {
13         this.countDown = countDown;
14     }
15     public String status() {
16         return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff ! " ) + "), ";
17     }
18     public void run() {
19         // TODO Auto-generated method stub
20         while(countDown -- > 0)
21         {
22             System.out.print(status());
23             Thread.yield();
24         }
25 
26     }
27 
28 }
29 
30 
31 
32 package a20190424;
33 
34 public class threadMain {
35     public static void main(String[] args) {
36         Thread t = new Thread(new Liftoff());
37         t.start();
38         System.out.println("Waiting for Liftoff");
39     }
40 
41 }
View Code

输出结果

Waiting for Liftoff
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff ! ),

5、线程状态

一个线程可以处在一下四种状态之一

  • 新建:线程对象已经建立,但是还没有启动,所以它还不能运行
  • 就绪:想成等待分配处理器。也就是说在这种状态下,只要调度程序把时间分配给线程,线程就可以运行,也就是说在任意时刻,线程可以运行可以不运行,只要调度程序能分配时间片给线程,它就可以运行,这不同于死亡和阻塞状态。
  • 死亡:线程死亡的方式往往是从run()方法返回。
  • 阻塞:线程能够运行,但是由某个条件(调用了sleep()  / wait()  /  等待某个I/O完成  /  试图在某个对象上调用其同步控制方法,但是对象锁不可用)阻止它的运行,当线程处于阻塞状态时,调度机制将忽略线程,不会分配给线程任何处理时间,直到线程重新进入了就绪状态,它才有可能执行操作。

 

 

posted @ 2019-04-27 22:13 六小白yy 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值