Java线程学习
线程初探
一.创建线程
在Java中创建一个线程有两种方式:
一、继承java.long.Thread类
public class TestThread extends Thread{......}
二、实现Runnable接口
public class TestThread implements Runnable{ @Override public void run() { } }
二、实现Thread类
如果选择继承自Thread的方式创建一个线程,只需要new一个它的对象:
TestThread thread = new TestThread();
而选择实现Runanble接口的方式创建线程,需要将其对象作为一个参数构造一个Thread。
Thread thread = new Thread(new TestThread());
单从线程的功能的角度来看,两种方式几乎没区别;从面向对象的角度来看,一个类已经继承自一个非Thread类,
但又须是一线程类,这是就选择第二种方式。这也是Java多态的表现。
三、启动线程
不管选择哪种方式创建线程,启动它需要调用start()方法,不是run方法,如:testThread.start();
当然单从一个Thread对象来看,的确可以在代码中直接调用ran()方法,但是这样是不会开启一个线程的;
只有调用start()方法后才会创建一个新的线程。如下例所示结果:
//这是测试线程类继承自Thread //在main()方法中用该类对象分别调用start()方法和run()方法 //打印结果,分析原因 public class TestThread extends Thread{ @Override public void run() { super.run(); int flag = 0; while(flag < 5){ try { flag++; Thread.sleep(1000 * flag); System.out.println("hello"); } catch (InterruptedException e) { e.printStackTrace(); } } } }
接下来在main()方法中调用两种方法:
import com.thread.TestThread; public class HelloThread { public static void main(String[] args) { TestThread thread = new TestThread(); // thread.run(); thread.start(); System.out.println(thread.getId()); System.out.println(thread.getName()); } }
调用start()方法后的执行结果如图所示:
调用run()方法后的执行结果如图所示:
start()一个线程,并不表示该线程立即运行,因为还需要得到cpu的时间片。
而是进入可运行状态,后面章节将会将线程的生命周期。
四、线程执行顺序
在没有同步机制的情况下,线程执行顺序,是不确定的。也就是说,线程执行顺序不受代码顺序影响。
这里就不给出代码。
五、小结
下面是从网上摘录的一段:
1、线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一个是虚拟机自己给的名字,一个是你自己的定的名字。在没有指定线程名字的情况下,虚拟机总会为线程指定名字,并且主线程的名字总是mian,非主线程的名字不确定。2、线程都可以设置名字,也可以获取线程的名字,连主线程也不例外。3、获取当前线程的对象的方法是:Thread.currentThread();4、在上面的代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。5、当线程目标run()方法结束时该线程完成。6、一旦线程启动,它就永远不能再重新启动。只有一个新的线程可以被启动,并且只能一次。一个可运行的线程或死线程可以被重新启动。7、线程的调度是JVM的一部分,在一个CPU的机器上上,实际上一次只能运行一个线程。一次只有一个线程栈执行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。众多可运行线程中的某一个会被选中做为当前线程。可运行线程被选择运行的顺序是没有保障的。8、尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列唱呢个一个队列的事实。9、尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。