再谈 Java中Runnable和Thread的区别

时间:2022-12-16 17:35:43

在面试中老有面试官问这个问题,个人觉得这个问题问的没有技术,一个死记硬背就能回答的很好。但是更深的回答是什么了,那就是直接回答源码吧。 thread类实现了runnable 接口 ,Runnable就是一个借口 ,只能我们去实现了才能用 对吧,不管是普通类 还是匿名内部类 ,最大的区别是我们的自己的实现类 没有办法启动线程,还是要借助于thread

结果就出现了线程的实现方法

package test8;

/**
* 方式一
* @author suifeng
*
*/
class myThread extends Thread{

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread());
}
}

/**
* 方式二
* @author suifeng
*
*/
class myRunable implements Runnable{

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread());
}
}
public class DT {

public static void main(String[] args) {
// TODO Auto-generated method stub

new myThread().start();

new Thread(new myRunable()).start();


}

}

但是不管是什么方法都需要 thread类的start 方法告诉JVM 启动线程 ,start()方法被 synchronized 修饰 ,在方法块里面有调用了start0() 方法
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();

/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);

boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}

 private native void start0();

start0方法是一个native 方法,直接调用的JVM C语言方法,才能启动一个线程 ,所以只有我们有办法启动这个start0,就可以自己创建一个线程 但是他又是一个私有方法 好吧,先我们来东东手,以后再也不用老是在实现runnable和在start()了


package test8;

import java.lang.Thread.State;
import java.lang.Thread.UncaughtExceptionHandler;

interface Work {

void work();
}

/**
* 装饰模式
* @author suifeng
*
*/
class Mthread implements Runnable {
Thread dt;
Work w;

public Mthread(Work w) {
dt = new Thread(this);
this.w = w;
dt.start();
}

public int hashCode() {
return dt.hashCode();
}

public boolean equals(Object obj) {
return dt.equals(obj);
}

public void start() {
dt.start();
}

// ...
public void run() {
w.work();
}

public final void stop() {
dt.stop();
}

public final void stop(Throwable obj) {
dt.stop(obj);
}

public void interrupt() {
dt.interrupt();
}

public boolean isInterrupted() {
return dt.isInterrupted();
}

public void destroy() {
dt.destroy();
}

public final boolean isAlive() {
return dt.isAlive();
}

public final void suspend() {
dt.suspend();
}

public final void resume() {
dt.resume();
}

public final void setPriority(int newPriority) {
dt.setPriority(newPriority);
}

public final int getPriority() {
return dt.getPriority();
}

public final void setName(String name) {
dt.setName(name);
}

public final String getName() {
return dt.getName();
}

public final ThreadGroup getThreadGroup() {
return dt.getThreadGroup();
}

public int countStackFrames() {
return dt.countStackFrames();
}

public final void join(long millis) throws InterruptedException {
dt.join(millis);
}

public final void join(long millis, int nanos) throws InterruptedException {
dt.join(millis, nanos);
}

public final void join() throws InterruptedException {
dt.join();
}

public final void setDaemon(boolean on) {
dt.setDaemon(on);
}

public final boolean isDaemon() {
return dt.isDaemon();
}

public final void checkAccess() {
dt.checkAccess();
}

public String toString() {
return dt.toString();
}

public ClassLoader getContextClassLoader() {
return dt.getContextClassLoader();
}

public void setContextClassLoader(ClassLoader cl) {
dt.setContextClassLoader(cl);
}

public StackTraceElement[] getStackTrace() {
return dt.getStackTrace();
}

public long getId() {
return dt.getId();
}

public State getState() {
return dt.getState();
}

public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return dt.getUncaughtExceptionHandler();
}

public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
dt.setUncaughtExceptionHandler(eh);
}
}

public class DthredTest {
public static void main(String[] args) {

new Mthread(new Work() {

@Override
public void work() {

System.out.println(Thread.currentThread());
}
});

new Mthread(new Work() {

@Override
public void work() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread());
}
});


while (Thread.activeCount() > 1) {
Thread.yield();
}

}
}