线程的start方法剖析

线程的start方法剖析

public synchronized void start() {
    if (threadStatus!=0)
    throw new IllegalThreadStateException();
    group.add(this);
    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started){
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
        }
    }
}
Thread start方法源码 总结
public synchronized void start() {
if (threadStatus!=0) ·Thread被构造后的NEW状态,事实上threadStatus这个内部属性为0
throw new IllegalThreadStateException(); ·不能两次启动Thread,否则就会出现IllegalThreadStateException异常。

·一个线程生命周期结束,也就是到了TERMINATED状态,再次调用start方法是不允许的,也就是说TERMINATED状态是没有办法回到RUNNABLE/RUNNING状态的。
group.add(this); ·线程启动后将会被加入到一个ThreadGroup中,后文中我们将详细介绍ThreadGroup。
boolean started = false;
try {
start0(); JDK的官方文档:※ Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
上面这句话的意思是:在开始执行这个线程时,JVM将会调用该线程的run方法,换言之,run方法是被JNI方法start0()调用的。
started = true;
} finally {
try {
if (!started){
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
}
}
}

执行单元

线程的真正的执行逻辑是在run方法中,通常我们会把run方法称为线程的执行单元

模板设计模式在Thread中的应用

其实Thread的run和start就是一个比较典型的模板设计模式,父类编写算法结构代码,子类实现逻辑细节
public class TemplateMethod {
    // 父类编写算法结构代码,
    public final void print(String message) {
        System.out.println("######befor-add-logic##########");
        wrapPrint(message);
        System.out.println("######after-add-logic##########");

    }
    protected void wrapPrint(String message) {
    }

    public static void main(String[] args) {

        // 子类实现逻辑细节
        TemplateMethod t1 = new TemplateMethod(){
            @Override
            protected void wrapPrint(String message) {
                System.out.println("*"+message+"*");
            }
        };
        t1.print("Hello Thread");
    }
}

策略模式在Thread中的应用

无论是Runnable的run方法,还是Thread类本身的run方法,都是想将线程的控制本身业务逻辑的运行分离开来,达到职责分明、功能单一的原则,这一点与GoF设计模式中的策略设计模式很相似
public interface RowHandler<T> {
    T handle(ResultSet rs);
}

public class RecordQuery {
    private final Connection connection;

    public RecordQuery(Connection connection) {
        this.connection = connection;
    }

    public <T> T query(RowHandler<T> handler, String sql, Object... params) throws SQLException {
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            int index = 1;
            for (Object param : params) {
                stmt.setObject(index++, param);
            }
            ResultSet resultSet = stmt.executeQuery();
            return handler.handle(resultSet);//①调用RowHandler
        }
    }
}
上面这段代码的好处是可以用query方法应对任何数据库的查询,返回结果的不同只会因为你传入RowHandler的不同而不同,同样RecordQuery只负责数据的获取,而RowHandler则负责数据的加工,职责分明,每个类均功能单一
相信通过这个简单的示例就类比Thread和Runnable之间的关系。

-----------------------------------------------------------------------------读书笔记摘自书名:Java高并发编程详解:多线程与架构设计 作者:汪文君
线程的start方法剖析_第1张图片

你可能感兴趣的:(并发编程,jvm,java,c#)