1、线程
每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务。多线程好处:解决了多部分同时运行的问题。多线程的弊端:线程太多回到效率的降低。其实应用程序的执行都是cpu在做着快速的切换完成的,这个切换是随机的。
JVM启动时就启动了多个线程,至少有两个线程可以分析的出来。
[1-1]执行main函数的线程,该线程的任务代码都定义在main函数中。
[1-2]负责垃圾回收的线程。
2、创建线程
[2-1]创建线程方法一:即继承thread类:可以通过Thread的getName获取线程的名称 Thread-编号(从0开始),主线程的名字就是main。
class Demo extends Thread {
private String name;
public Demo(String name) {
this.name = name;
}
public void run() {
for (int x = 0; x < 10; x++) {
System.out.println(name + "....x=" + x + ".....name="
+ Thread.currentThread().getName());
}
}
}
class Test {
public static void main(String[] args) {
Thread t1 = new Thread();
Demo d1 = new Demo("旺财");
Demo d2 = new Demo("xiaoqiang");
d1.start();// 开启线程,调用run方法。
d2.start();
System.out.println("over...." + Thread.currentThread().getName());
}
}
[2-2]创建线程方法二:实现Runnable接口,实现Runnable接口的好处:
[2-2-1]将线程的任务从线程的子类中分离出来,进行了单独的封装。按照面向对象的思想将任务的封装成对象。
[2-2-2]避免了java单继承的局限性。所以,创建线程的第二种方式较为常用。
class Demo implements Runnable {
public void run() {
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName() + "....." + x);
}
}
}
class Test {
public static void main(String[] args) {
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t2.start();
}
}
结论:Thread thread = new Thread(new Runnable()(){}) Runnable对象不是线程,是run方法的宿主,run方法即任务。
3、线程Thread.stop()的用法
这里要明确的一点,不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制。线程休眠的目的是使线程让出CPU的最简单的做法之一,线程休眠时候,会将CPU资源交给其他线程,以便能轮换执行,当休眠一定时间后,线程会苏醒,进入准备状态等待执行。
线程休眠的方法是Thread.sleep(long millis) 和Thread.sleep(long millis, int nanos) ,均为静态方法,那调用sleep休眠的哪个线程呢?简单说,哪个线程调用sleep,就休眠哪个线程。
为什么不能使用Thread.stop()方法?从SUN的官方文档可以得知,调用Thread.stop()方法是不安全的,这是因为当调用Thread.stop()方法时,会发生下面两件事:1、 即刻抛出ThreadDeath异常,在线程的run()方法内,任何一点都有可能抛出ThreadDeathError,包括在catch或finally语句中。2、 释放该线程所持有的对象锁,那么该对象的同步方法就放开了。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。
4、线程中一些方法的说明。
[4-1]sleep()使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。