码迷,mamicode.com
首页 > 编程语言 > 详细

多线程--线程的创建与启动

时间:2019-04-20 21:39:07      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:interrupt   静态方法   stat   ace   获得   情况下   class   前端   catch   

创建一个线程,Java提供三种方法

(1)通过实现Runnable接口,重写run方法

(2)通过继承Thread类本身,--必须重写

(3)通过Callable和Future创建线程

Thread类的方法

void start()使该线程开始执行,Java虚拟机调用该线程的run方法。

final void setName(String name)改变线程名称,使之与参数name相同

setPriority(int priority)更改线程的优先级

join(long millisec)等待该线程终止的时间最长为milli毫秒

interrupt()中断线程

boolean isAlive()测试线程是否处于活动状态

上述方法被Thread对象调用

下面的方法是Thread类的静态方法static

yield()放弃CPU的使用权力

sleep(long millisec)休眠线程

currentThread()获得正在执行的线程对象

 

概念解析:

并行:是真正的同时。

并发:通过CPU调度算法,用户看上去同时执行,实际上从CPU层面上不是真正同时。

线程安全:并发情况下,多线程使用,线程调度顺序不影响任何结果。

同步:Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问称为线程安全的--结果正确。

 

Thread和Runnable的区别

如果一个类继承Thread,则不合适资源共享,但是如果实现了Runnable接口,则很容易实现资源共享。

线程是CPU的调度单位,进程是操作系统的调度单位。

 

Method类中有个方法invoke()

public Object invoke(Object obj,Object ...args)

通俗点讲就是:对象调用的方法(对象.参数)


 

守护线程(DaemonThread)

守护线程具有最低的优先级;

是用来服务用户线程的。

(1)thread.setDaemon(true)必须在thread.start()之前设置。

(2)在Daemon线程中产生的新的线程也是Daemon的。

(3)守护线程不去访问固有的资源,如文件,数据库。

 

用户线程(userThread)

Thread和Runnable创建出来的线程。

 

线程的生命周期大体分为5种状态

1.New:通过new创建了Thread类或其子类对象。

2.Runnable: a)指Thread类对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU;b)线程在处于Runnable状态时并没有运行完自己的run方法,时间片用完之后回到Runnable状态; c) 处于Blocked状态的线程结束当前的Blocked状态之后重新回到Runnable状态。

3.Running:线程已获CPU运行。

4.Dead:处于Running的线程,执行完run方法之后,就变成了Dead状态。

5.Blocked:处于Running状态的线程出于某种原因,让出当前CPU 给其他线程。


 

线程的创建与启动

继承Thread类:重写run方法

 1 package NiuMuThread;
 2 
 3 public class MyThread extends Thread{
 4 
 5     @Override
 6     public void run() {
 7         // TODO Auto-generated method stub
 8         for(int i=0;i<100;i++) {
 9 //            线程的静态方法-----当前线程----的名字
10             System.out.println(Thread.currentThread().getName()+":"+i);
11             try {
12                 Thread.sleep(100);
13             } catch (InterruptedException e) {
14                 // TODO Auto-generated catch block
15                 e.printStackTrace();
16             }
17         }
18     }
19 }

实现Runnable接口:重写run方法

 1 package NiuMuThread;
 2 
 3 public class MyThread2 implements Runnable{
 4 
 5     @Override
 6     public void run() {
 7         // TODO Auto-generated method stub
 8         for(int i=0;i<100;i++) {
 9 //            线程的静态方法-----当前线程----的名字
10             System.out.println(Thread.currentThread().getName()+":"+i);
11             try {
12                 Thread.sleep(100);
13             } catch (InterruptedException e) {
14                 // TODO Auto-generated catch block
15                 e.printStackTrace();
16             }
17         }
18     }
19 }

测试:

 1 package NiuMuThread;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         //第一个线程
 7         MyThread thread=new MyThread();
 8         //第三个线程
 9         MyThread2 r=new MyThread2();
10         
11         Thread th2=new Thread(r);
12         thread.start();//启动线程
13         th2.start();
14         
15         //第二个线程
16         for(int i=0;i<100;i++) {
17 //            线程的静态方法-----当前线程----的名字
18             System.out.println(Thread.currentThread().getName()+":"+i);
19             try {
20                 Thread.sleep(100);
21             } catch (InterruptedException e) {
22                 // TODO Auto-generated catch block
23                 e.printStackTrace();
24             }
25         }
26     }
27 }

注意:通过实现Runnable接口的,需要 new Thread(runnable),才能创建线程对象

***在线程的Thread对象上调用start()方法,而不是run()或者别的方法。

 

一些常见的问题

1.线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一是虚拟机自己给的名字,或者是你自己定的名字。在没指定线程名字的情况下,虚拟机会为线程指定名字,主线程的名字是main,非主线程的名字不确定。

2.线程都可以设置名字,也可以获取线程的名字。

3.获取当前线程的对象的方法是:Thread.currentThread();

4.在上面代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。

5.当线程目标run()方法结束时线程完成。

6.一旦线程启动,它就永远不能在重新启动。只有一个新的线程可以被重新启动,并且只能一次。一个可运行的线程或者死线程可以被重新启动。

7.线程的调度是JVM的一部分,在一个CPU的机器上,实际上一次只能运行一个线程。一次只有一个线程栈运行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。

众多可运行线程中的某一个会被选中作为当前线程。可运行线程被选择的顺序是没有保障的。

8.尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列。

9.尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程的调度方式。

 

多线程--线程的创建与启动

标签:interrupt   静态方法   stat   ace   获得   情况下   class   前端   catch   

原文地址:https://www.cnblogs.com/xjs1874704478/p/10742672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!