线程对象是能够产生线程的对象。好比在Java平台中Thread对象,Runnable对象。线程,是指正在执行的一个指点令序列。在java平台上是指从一个线程对象的start()开始,运行run方法体中的那一段相对独立的过程。相比于多进程,多线程的优点有:java
(1)进程之间不能共享数据,线程能够;程序员
(2)系统建立进程须要为该进程从新分配系统资源,故建立线程代价比较小;面试
(3)Java语言内置了多线程功能支持,简化了java多线程编程。编程
1、建立线程和启动多线程
(1)继承Thread类建立线程类ide
经过继承Thread类建立线程类的具体步骤和具体代码以下:性能
• 定义一个继承Thread类的子类,并重写该类的run()方法;spa
• 建立Thread子类的实例,即建立了线程对象;.net
• 调用该线程对象的start()方法启动线程。线程
class SomeThead extends Thraad { public void run() { //所要重写的方法
} } public static void main(String[] args){ SomeThread oneThread = new SomeThread(); 步骤3:启动线程: oneThread.start(); }
(2)实现Runnable接口建立线程类
经过实现Runnable接口建立线程类的具体步骤和具体代码以下:
• 定义Runnable接口的实现类,并重写该接口的run()方法;
• 建立Runnable实现类的实例,并以此实例做为Thread的target对象,即该Thread对象才是真正的线程对象。
class SomeRunnable implements Runnable { public void run() { //所要重写的方法
} } Runnable oneRunnable = new SomeRunnable(); Thread oneThread = new Thread(oneRunnable); oneThread.start();
以上的两种方法都可实现建立线程类
然而,本魔王一开始乍一看的时候感受大致上好像并无什么区别,但事实显然并无这么简单,试问一下,当使用Thread时候若有需求要求继承其余类的时候,是能够用extend继承父类的域,那万一要继承的不仅是一个父类呢,Thread毕竟只是一个类,不是接口,诶!!对了,这时候用Runnable就会方便不少,下面为你们总结的是Runnable与Thread的相关性。
1) Thread是一个类,Runnable是一个接口;
2) Thread类实现了Runnable接口,重写了run方法.
3) Runnable是一个接口,定义一个类实现接口的同时还能够继承其余的类 ; Runnable 支持多继承的写法;
4) Runable能够简单的实现数据的共享 ;Thread不太好实现;其实均可以实现
5) Runnable适合多个相同的程序代码的线程去处理同一个资源,避免Java中的单继承的限制,增长程序的健壮性,代码能够被多个线程共享,代码和数据独立。线程池只能放入实现Runnable 类线程,不能直接放入继承Thread的类.
在面试的时候,不少面试官都喜欢问一些关于线程状态的问题,可能很少问的特别细,但起码道理咱们得说的出来,下图是线程的生命周期,就挑几个常见的给你们解释的,其实有一些是我本身概括的,也有一些是网上dd下来的,懂的是什么道理,本身整理一套白话最好。
用new关键字和Thread类或其子类创建一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有本身的内存空间,经过调用start方法进入就绪状态(runnable),它仅仅做为一个对象实例存在, JVM没有为其分配CPU时间片和其余线程运行资源;。
注意:不能对已经启动的线程再次调用start()方法,不然会出现Java.lang.IllegalThreadStateException异常。
Java提供了一些便捷的方法用于线程状态的控制,就举几个经常使用的例子,多了我也不会。具体以下:
一、线程睡眠——sleep
若是咱们须要让当前正在执行的线程暂停一段时间,并进入阻塞状态,则能够经过调用Thread的sleep方法。
注:
(1)sleep是静态方法,最好不要用Thread的实例对象调用它,由于它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。以下面的例子:
1 package day7_3HomeWork; 2 3 public class Thread_text { 4 5 public static void main(String[] args) { 6 Thread_input ti = new Thread_input(); 7 ti.start(); 8 9 } 10 } 11 class Thread_input extends Thread{ 12 String[] str = {"我","我爱","我爱福","我爱福建","我爱福建工","我爱福建工程","我爱福建工程学","我爱福建工程学院"}; 13 @Override 14 public void run() { 15 // TODO Auto-generated method stub 16 for(int i=0;i<str.length;i++) 17 { 18 System.out.println(str[i]); 19 try { 20 sleep(2000); 21 } catch (InterruptedException e) { 22 // TODO Auto-generated catch block 23 e.printStackTrace(); 24 } 25 } 26 } 27 }
至关于只是暂停当前的进程运行,线程处于阻塞状态,在2000mills的睡眠时间结束的时候才能从新变回就绪状态,而就绪状态进入到运行状态,是由系统控制的,咱们不可能精准的去干涉它,因此若是调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。下图是sleep的方法,须要传入的是一个long mills的参数,这是毫秒的单位。
(2)Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提升程序的执行效率。可是无论程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能作到精准控制。