线程的创建
Java中创建线程有两种方式,一是继承Thread类,而是实现Runnable接口。下面一一来看。
- 继承Thread类:
public class Demo1 extends Thread { public Demo1(String name) { super(name); }
@Override public void run() { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName() + "运行:" + i); try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }
public static void main(String[] args) { Demo1 th1 = new Demo1("自定义线程"); th1.start(); //注意:这里不能直接调用run方法 for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName() + "运行:" + i); } } }
- 实现Runnable接口:
Demo2:
public class Demo2 implements Runnable { @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName() + "运行:" + i); } } public static void main(String[] args) { Demo2 demo = new Demo2(); Thread thread1 = new Thread(demo,"A"); Thread thread2 = new Thread(demo,"B"); thread1.start(); thread2.start(); } }
以上两个demo都是能够实现交替运行的结果。
这里首先要注意的点是:当我们创建了线程对象后我们调用的是start()方法,而不是run()方法,如果直接调用了run()方法却不会出现交替执行的现象,Why?
- 这是因为一个线程一旦开启,那么线程就会执行run方法中的代码,run方法千万不能直接调用,直接调用run方法就相当调用了一个普通的方法而已并没有开启新的线程。
- 如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是得顺序地执行,等待run方法体执行完毕后才可继续执行后面的代码,这样就没有达到写线程的目的。
- 而调用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。
- 其实,直接看源代码会更有底~~(当然我水平渣渣只看懂个大概 , 没法解析下源码唉 - -)
- 两种方式中使用实现Runnable接口的方式更为好:
- 适合多个相同的程序代码的线程去处理同一个资源。
- 可以避免java中的单继承的限制,因为java单继承 ,多实现的,如果一个类是由基类继承下来的,那么意味它不能够使用extends方式来实现多线程了。
- 增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。