關於StringBuffer的insert(int offset, int i)方法中的執行緒安全和動態鏈接的問題

2020-08-09 01:03:25

首先我們知道StringBuffer是一個執行緒安全的類,主要實現了字串的append。
StringBuffer主要是通過在方法上加synchronized關鍵字來實現同步,
但在這個方法上沒有新增,這就引入了這篇文章的話題:

insert()方法是如何保證該方法是執行緒安全的

@Override
    public StringBuffer insert(int offset, int i) {
        // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
        // after conversion of i to String by super class method
        // Ditto for toStringCache clearing
        super.insert(offset, i);
        return this;
    }

這是insert的原始碼,我們進入super.insert(offset, i)方法檢視

public AbstractStringBuilder insert(int offset, int i) {
        return insert(offset, String.valueOf(i));
    }

該程式碼塊是在AbstractStringBuilder 類中的,這個呼叫的insert(offset, String.valueOf(i))的方法是該類實現的,並不是同步方法,那麼他是怎麼保證執行緒安全的呢?

其實,在StringBuilder有和這個insert(offset, String.valueOf(i))方法簽名相同的方法,
在執行期間jvm該物件的實際型別找到和這個方法簽名相同的方法(通過自下而上的查詢),並把它存放在虛方法表中(ps:大致可以理解爲快取)。這是一個動態鏈接的過程。
這個過程中找到的此方法的實際實現就是

@Override
    public synchronized StringBuffer insert(int offset, char c) {
        toStringCache = null;
        super.insert(offset, c);
        return this;
    }

還是通過synchronized保證執行緒安全的。