Java多线程学习(一)

创建一个线程主要有两个方法:实现Runnable接口和继承Thread类。虽然Thread类底层也实现了Runnable接口,但在使用的时候两者还是有很大差别。

1. 继承Runnable接口:

public class TestRunnable implements Runnable{
    private String name;    //给线程一个名称,方便标识

     public TestRunnable(String name){
        this.name = name;
    }

    @Override
    public void run(){
        for(int i=0; i<10; i++){
            System.out.println(name+"正在运行:"+"   "+i);
        }
    }

    public static void main(String[] args){
        TestRunnable t1 = new TestRunnable("A");
        TestRunnable t2 = new TestRunnable("B");

        Thread thread1 = new Thread(t1);    //用实现Runna接口的对象来创建线程
          Thread thread2 = new Thread(t2);

        thread1.start();
        thread2.start();
    }
}
运行结果为:

A正在运行:   0
B正在运行:   0
A正在运行:   1
B正在运行:   1
A正在运行:   2
B正在运行:   2
A正在运行:   3
A正在运行:   4
B正在运行:   3
A正在运行:   5
B正在运行:   4
A正在运行:   6
B正在运行:   5
A正在运行:   7
B正在运行:   6
A正在运行:   8
B正在运行:   7
A正在运行:   9
B正在运行:   8
B正在运行:   9

再运行一次,发现结果不一样:

A正在运行:   0
B正在运行:   0
A正在运行:   1
B正在运行:   1
A正在运行:   2
B正在运行:   2
A正在运行:   3
A正在运行:   4
A正在运行:   5
A正在运行:   6
A正在运行:   7
A正在运行:   8
A正在运行:   9
B正在运行:   3
B正在运行:   4
B正在运行:   5
B正在运行:   6
B正在运行:   7
B正在运行:   8
B正在运行:   9

这是因为每次在运行中,线程都要抢夺CPU资源,由于优先级不同,最终执行的顺序和结果也不同。

2. 继承Thread类:

public class TestThread extends Thread{
    private String name;

    public TestThread(String name) {
        this.name = name;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(name + "正在运行   " + i);
        }
    }

    public static void main(String[] args) {
        TestThread h1 = new TestThread("A");
        TestThread h2 = new TestThread("B");
        h1.start();
        h2.start();
    }
}
运行结果:

A正在运行   0
B正在运行   0
A正在运行   1
B正在运行   1
A正在运行   2
B正在运行   2
A正在运行   3
B正在运行   3
A正在运行   4
B正在运行   4
A正在运行   5
B正在运行   5
A正在运行   6
B正在运行   6
A正在运行   7
B正在运行   7
A正在运行   8
A正在运行   9
B正在运行   8
B正在运行   9

3. Thread与Runnable比较:

看上去Thread的写法更简洁,只需要创建对象并start就好。如果不使用公共资源,确实用Thread更方便。但如果有一个变量是多个线程间共享的,怎么办?

在TestThread对象中增加一个字段count。

public class TestThread extends Thread{
    private String name;
    private int count = 10;

    public TestThread(String name) {
        this.name = name;
    }

    public void run() {
        for (int i = 0; i < 10; i++) {
            --count;
            System.out.println(name + "正在运行   " + i + "   count还有"+count);
        }
    }

    public static void main(String[] args) {
        TestThread h1 = new TestThread("A");
        TestThread h2 = new TestThread("B");
        h1.start();
        h2.start();
    }
}
结果怎样可以猜出来,这根本是两个对象,各计算各的。

A正在运行   0   count还有9
B正在运行   0   count还有9
B正在运行   1   count还有8
B正在运行   2   count还有7
B正在运行   3   count还有6
B正在运行   4   count还有5
B正在运行   5   count还有4
B正在运行   6   count还有3
B正在运行   7   count还有2
B正在运行   8   count还有1
A正在运行   1   count还有8
B正在运行   9   count还有0
A正在运行   2   count还有7
A正在运行   3   count还有6
A正在运行   4   count还有5
A正在运行   5   count还有4
A正在运行   6   count还有3
A正在运行   7   count还有2
A正在运行   8   count还有1
A正在运行   9   count还有0

那如果换成static类型的变量呢?static为类的所有对象维护一个公共变量。

A正在运行   0   count还有9
B正在运行   0   count还有8
A正在运行   1   count还有7
B正在运行   1   count还有6
A正在运行   2   count还有5
B正在运行   2   count还有4
A正在运行   3   count还有3
B正在运行   3   count还有2
B正在运行   4   count还有0
B正在运行   5   count还有-1
B正在运行   6   count还有-2
B正在运行   7   count还有-3
B正在运行   8   count还有-4
B正在运行   9   count还有-5
A正在运行   4   count还有1
A正在运行   5   count还有-6
A正在运行   6   count还有-7
A正在运行   7   count还有-8
A正在运行   8   count还有-9
A正在运行   9   count还有-10

乍一看似乎不错,但如果仔细观察,会发现顺序和数字根本不对。所以用Thread不能正确的实现资源共享。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章