java

Java多线程的实现方法

2015-10-04  本文已影响251人  许宏川

我们知道一个程序通常是一个进程,而一个进程可以有多个线程。
线程是不规律的在交替进行,哪个线程抢到cpu时间谁就运行。而线程运行过程中cpu也可能被其他线程抢走,然后又会继续抢cpu时间。直到线程运行结束或者所在进程已经被关掉。

Java类库已经为我们提供了一个线程基类Thread,因此创建线程非常简单。

方法一

创建两个类FirstThread和SecondThread都继承Thread类,然后重写run方法。

public class FirstThread extends Thread {

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("F --> " + i);
        }
    }
}
public class SecondThread extends Thread {

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("S --> " + i);
        }
    }
}

测试代码:

public class Test {

    public static void main(String[] args) {
        FirstThread ft = new FirstThread();
        SecondThread st = new SecondThread();
        // 用start()调用线程的run方法。
        // 注意这里不能直接调用run(),否则就和普通的调用方法没区别不会启动线程
        ft.start();
        st.start();
    }

}

部分执行结果:

F --> 0
F --> 1
F --> 2
F --> 3
F --> 4
F --> 5
F --> 6
F --> 7
F --> 8
F --> 9
F --> 10
F --> 11
F --> 12
F --> 13
S --> 0
S --> 1
S --> 2
S --> 3
S --> 4
S --> 5
S --> 6
S --> 7
F --> 14
F --> 15
F --> 16
F --> 17
F --> 18
F --> 19
S --> 8
S --> 9
S --> 10
F --> 20

运行结果可以看到两个线程不规律的交互进行互相抢cpu时间。
所以创建线程只需要继承Thread类,然后在重写的run方法里写下想在线程里执行的代码即可。注意调用时用通过调用start方法来启动线程而不能直接调用run方法。否则只是普通的调用方法并没有多线程的效果。
另外此时程序可不止两个线程。一共有四个线程,分别是Main方法所在的主线程FirstThread、SecondThread和垃圾回收线程。

方法二

因为Java只能单继承,继承了Thread类就不能再继承别的类了。这样显得不够灵活,所以实现继承更推崇的是让线程类实现Runnable接口。
以FirstThread为例:

public class FirstThread implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("F --> " + i);
        }
    }
}

测试代码要改为直接创建Thread对象但是把实现了Runnable接口的类的对象作为参数传进去。

public class Test {

    public static void main(String[] args) {
        Thread ft = new Thread(new FirstThread());
        Thread st = new Thread(new SecondThread());
        // 用start()调用线程的run方法。
        // 注意这里不能直接调用run(),否则就和普通的调用方法没区别不会启动线程
        ft.start();
        st.start();
    }

}

以上可以起到和方法一一致的效果。
实际使用中这种实现线程的方法经常会写成匿名内部类的形式,如以下这样:

new Thread() {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("匿名线程 --> " + i);
        }
    }
}.start();

Callable和Future

以上实现线程的方式虽然简单但是有缺陷,就是run方法是void类型没有返回值,而我们有时候希望线程执行完毕后返回一个结果。
代码共享

本文代码下载:百度网盘

上一篇 下一篇

猜你喜欢

热点阅读