Java线程的两种实现方式,以及它们之间的联系和区别

Java线程的两种实现方式,以及它们之间的联系和区别

本文将从继承Thread类和实现Runnable接口讲起,并阐述它们的联系和区别。

实现方式1:继承Thread类,并重写run函数

  • 代码实现
package Toy;

/**
 * 重写的run方法:使成员变量x增加200
 */
public class ToyThead extends Thread{

    int x ;
    
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {
            x += 2 ;
        }
    }
    
}
  • 主函数
package Toy;

public class Toymain {
    
    public static void main(String[] args) throws InterruptedException {
        ToyThead toyThead1 = new ToyThead();
        toyThead1.x = 10;
        
        // 启动线程 必须使用start()方法  因为 直接调用run()方法 相当于调用一个普通的方法 
        toyThead1.start();
        
        //此处我们让程序休眠了1秒钟,假如不让程序休眠的话,线程可能还处在就绪态 没有运行,x就被打印出来了。
        Thread.sleep(1000);
        
        System.out.println(toyThead1.x);

    }
}
  • 结果: 210

实现方式2:实现Runnable接口,并重写run函数

  • 代码实现
package Toy;

public class ToyRunnable implements Runnable{

    int x ;
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            x += 2;
        }
    }
}
  • 主函数
package Toy;

public class Toymain {
    
    public static void main(String[] args) throws InterruptedException {
        ToyRunnable tr = new ToyRunnable();
        tr.x = 10;
        tr.run();
        Thread.sleep(1000);
        System.out.println(tr.x);
        
    }
}
// 其他启动方法:
// PrimeRun p = new PrimeRun(143);
// new Thread(p).start();

结果:210

两种实现方式的联系和区别

  • 联系: public class Thread implements Runnable{};
  • 实现Rannabled接口的优点:避免了java的单继承的局限性
  • 区别:
    • 继承Thread类 创建线程,不能使用多个线程来共享同一个对象的资源
    • 实现 Runnable 接口创建线程,可以使用多个线程来共享同一个对象的资源
    • 代码验证:
  • 继承Thread类
package Toy;
//
public class ToyThead extends Thread{

    int x ;
	
    @Override
    public void run(){
        for (int i = 0; ; i++) {
            x += 2 ;
            try {
                sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

  • 实现 Runnable 接口
package Toy;

import static java.lang.Thread.sleep;

public class ToyRunnable implements Runnable{

    int x ;
    
    @Override
    public void run() {
        for (int i = 0; ; i++) {
            x += 2;
            try {
                sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

  • 主函数
package Toy;

public class Toymain {
    
    public static void main(String[] args) throws InterruptedException {
        ToyThead toyThead1 = new ToyThead();//Thread线程1
        toyThead1.x = 0;
        toyThead1.start();

        ToyThead toyThead2 = new ToyThead();//Thread线程2
        toyThead2.x = 0;
        toyThead2.start();

        Thread.sleep(1000);

        System.out.println(toyThead1.x);
        System.out.println(toyThead2.x);

        ToyRunnable tr = new ToyRunnable(); //实现Runnable接口的线程
        tr.x = 0;
        Thread tr1 = new Thread(tr); //线程1
        Thread tr2 = new Thread(tr);//线程2

        tr1.start();
        tr2.start();
        Thread.sleep(1000);
        System.out.println(tr.x);

    }
}

  • 运行结果:

image

由此可见,实现 Runnable 接口创建线程,两个线程都可以将成员变量x变大,所以它们共享同一个对象的资源。

posted @ 2022-04-16 16:33  classic123  阅读(78)  评论(0编辑  收藏  举报