通过继承Thread类方法,区分run()和start(),我们发现,其实start()方法也是会去调用run()方法的,但是为什么start()方法会出现多线程执行,而run()方法只会顺序执行呢?因为启动start()方法的时候,并没有立刻调用run()方法,而是将该线程设定为就绪状态,只有得到CPU时间片的时候,线程才开始运行。run()方法本身等级只是一个普通方法,如果直接调用run()方法,程序中依然只有主线程一个线程,执行路径只有一条,只能顺序执行,只能将run()方法中的命令执行完以后才可以执行后面的命令。将run()方法设定为public void,启动start()方法后,将会根据cpu资源自动调用run()方法。

public class TestThread extends Thread{
    
    public TestThread(){};
    
    private String name;
    public TestThread(String name){
        this.name = name;
    }
    
    public void run(){
        for (int i = 0; i < 3; i++) {
            System.out.println(name+"is"+i);
        }
    }

    public static void main(String[] args) {
        TestThread th1 = new TestThread("A");
        TestThread th2 = new TestThread("B");
        th1.run();    //当调用run()方法时,执行顺序不会变,是按照顺序执行的。结果为1
        th2.run();    //当调用start()方法时,执行顺序不一定,结果为2,任意执行。
    }

}

1~~~~~~~~~~~~~~~~~~~~~ Ais0 Ais1 Ais2 Bis0 Bis1 Bis2
2~~~~~~~~~~~~~~~~~~~~~   

Ais0
Ais1
Bis0
Bis1
Bis2
Ais2

通过实现Runnable()接口,本质都一样,后面又用Thread类生成线程对象的。Thread类其实也是通过实现Runnable()接口的。

package com.enjoyor.soa.traffic.server.nmim.thread;

public class TestThread implements Runnable{
    
    public TestThread(){};
    
    private String name;
    public TestThread(String name){
        this.name = name;
    }
    
    public void run(){
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName()+name+"is"+i);//Thread.getName获取正在运行的线程名称,如果你不运行,也无法指定知道到底是什么啊!
        }
    }

    public static void main(String[] args) {
        TestThread th1 = new TestThread("A");
        TestThread th2 = new TestThread("B");
        Thread newTh1 = new Thread(new TestThread("X"),"线程1");//也可以这样写,简洁的将类的生成冗余去掉,反正th1也只是过渡一下,能够指向确定的类就行,有没有代号没关系。
        Thread newTh2 = new Thread(th2,"线程2");//这里需要new一个Thread对象
        newTh1.start();    
        newTh2.start();
    }

}

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源(比如车票)

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。


package com.enjoyor.soa.traffic.server.nmim.thread;


public class TestThread extends Thread{

public TestThread(){};

private int appleCount = 4;

public void run(){
for (int i = 0; i < 3; i++) {
if(appleCount>0){
System.out.println(Thread.currentThread().getName()+"is"+appleCount--);
}

}
}


public static void main(String[] args) {
TestThread newTh1 = new TestThread();
TestThread newTh2 = new TestThread();
newTh1.start();
newTh2.start();
}
}


Thread-0is4
Thread-0is3
Thread-0is2
Thread-1is4
Thread-1is3
Thread-1is2

 

 

package com.enjoyor.soa.traffic.server.nmim.thread;

public class TestThread implements Runnable{
    
    public TestThread(){};
    
    private int appleCount = 4;
    
    public void run(){
        for (int i = 0; i < 3; i++) {
            if(appleCount>0){
                System.out.println(Thread.currentThread().getName()+"is"+appleCount--);
            }
            
        }
    }

    public static void main(String[] args) {
        TestThread newTh1 = new TestThread();
        //TestThread newTh2 = new TestThread();  //区别就是在这里产生的,这里一个类可以通过两个线程去调用,类还是同一个,资源可以共享同步。而通过继承Threa类的类要实现多线程,只能生成多个自身类,就不再是同一个类了,无法做到资源共享。也就是一个类两个线程,和两个类两个线程的区别。
        Thread Th1 = new Thread(newTh1,"xl吃苹果");
        Thread Th2 = new Thread(newTh1,"wl吃苹果");        
        Th1.start();    
        Th2.start();
    }
}

xl吃苹果is4
xl吃苹果is3
xl吃苹果is2
wl吃苹果is1

 

线程的方法有强制执行join(),中断interrupt,睡眠sleep(),转为守护(后台)进程setDaemon(true),优先级setPriority(int),礼让yield()。

 

 

 

 

 

参考文章:http://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html