Java 线程的创建

79 阅读2分钟

1. 线程的创建方式一:继承Thread类

步骤:
1. 创建一个继承于 Thread 类的子类
2. 重写 Thread 类的 run(),将此线程要执行的操作,声明在此方法体中
3. 创建当前 Thread 的子类的对象
4. 通过对象调用 start()
//1. 创建当前继承Thread类的子类
class Oversides extends Thread{
    //2. 重写Thread类的run()
    @Override
    public void run(){
        for(int i = 0;i < 100; i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    }
}
public class Thread_Test extends Thread {
    public static void main(String[] args) {
        //3. 创建当前Thread的子类对象
        Oversides o1 = new Oversides();
        //4. 通过对象调用start()
        o1.start();


        for(int i = 0;i < 100; i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    //方法2:实现类的匿名对象
    new Thread(){
        public void run(){
            for(int i = 0;i < 100; i++){
                if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " " + i);
                }
            }
        }
    }.start();
    }
}

Notice

能否使用t1.run()替换t1.start()的调用,实现分线程的创建和调用? 不能!------t1.run() 还是归属于main线程的
如果创建多个线程,每个线程执行的任务不一样,如何解决?
解决方法一:需要创建多个继承类,再重写run()
解决方法二:实现类的匿名对象。如上述方法2

2. 线程的创建方式二:实现Runnable接口

步骤
1. 创建一个实现Runnable接口的类
2. 实现接口中的run()。将此线程要执行的操作,声明在此方法体中
3. 创建当前实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
5 Thread类的实例调用start():1.启动线程 2调用当前线程的run()
//1. 创建一个实现Runnable接口的类
class OverS implements Runnable{
    //2. 实现接口中的run()。将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        for(int i = 0;i < 100; i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    }
}
public class Runnable_Test {
    public static void main(String[] args) {

        //3. 创建当前实现类的对象
        OverS s = new OverS();
        //4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(s);
        //5 Thread类的实例调用start():1.启动线程 2调用当前线程的run()
        t1.start();

        //main()方法对应的主线程执行的操作
        for(int i = 0;i < 100; i++){
            if(i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }

        //在创建一个线程
        Thread t2 = new Thread(s);
        t2.start();

        //方法二:使用实现Runnable接口的方式: (提供了Runnable接口匿名实现类的匿名对象)
        new Thread(new Runnable() {
            public void run() {
                for(int i = 0;i < 100; i++){
                    if(i % 2 == 0){
                        System.out.println(Thread.currentThread().getName() + " " + i);
                    }
                }
            }
        }).start();
    }
}

Notice

如果创建多个线程,每个线程执行的任务不一样,如何解决?
使用实现Runnable接口的方式: (提供了Runnable接口匿名实现类的匿名对象)。如上述方法二

3. 对比两种方式

共同点:
(1)启动线程,使用的都是Thread类中定义的start()
(2)创建的线程对象,都是Thread类或其子类的实例。
不同点:
    一个是类的继承,一个是接口的实现。
    建议使用实现Runnable接口的方式。
    Runnable方式的好处 :实现的方式,避免的类的单继承的局限性
                        更适合处理有共享数据的问题
                        实现了代码和数据的分离。
联系:
    public class Thread implements Runnable (代理模式)