然而,在线程类方法中,必须为每个线程访问创建单独的实例。因此,为每个类实例分配不同的内存,每个类实例都有单独的计数器,值保持不变,这意味着不会发生增量,因为对象引用都不相同。
当您想从线程组访问相同的资源时,请使用Runnable接口。这里避免使用线程类,因为多个对象创建会消耗更多内存,并且会成为一个很大的性能开销。
实现Runnable的类不是线程,而是一个类。要使一个可运行的线程成为线程,您需要创建线程实例并将其作为目标传入。
在大多数情况下,如果只计划重写run()方法而不打算重写其他线程方法,则应该使用Runnable接口。这一点很重要,因为类不应该被子类化,除非程序员打算修改或增强类的基本行为。
当需要扩展超类时,实现可运行接口比使用线程类更合适。因为我们可以在实现Runnable接口时扩展另一个类来生成线程。
class RunnableImpl implements Runnable {
private int count = 0;
public void run() {
count ++;
System.out.println("RunnableImpl : count : " + count);
}
}
class ThreadExtends extends Thread {
private int count = 0;
public void run() {
count++;
System.out.println("ThreadExtends : count : " + count);
}
}
public class ThreadRunnableDemo {
public static void main(String args[]) throws Exception {
// 多个线程共享相同的对象.
RunnableImpl rc = new RunnableImpl();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000);
Thread t3 = new Thread(rc);
t3.start();
// 为每个线程访问创建新对象
ThreadExtends te1 = new ThreadExtends();
te1.start();
Thread.sleep(1000);
ThreadExtends te2 = new ThreadExtends();
te2.start();
Thread.sleep(1000);
ThreadExtends te3 = new ThreadExtends();
te3.start();
}
}
输出
RunnableImpl : count : 1
RunnableImpl : count : 2
RunnableImpl : count : 3
ThreadExtends : count : 1
ThreadExtends : count : 1
ThreadExtends : count : 1
备注:线程之间需要时间间隔,不然RunnableImpl的输出可能不会是1 2 3 顺序递增