Path: blob/master/test/hotspot/jtreg/vmTestbase/gc/gctests/StringInternSyncWithGC/StringGenerator.java
41155 views
/*1* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package gc.gctests.StringInternSyncWithGC;2324import java.lang.ref.Reference;25import java.lang.ref.SoftReference;26import java.lang.ref.WeakReference;27import java.util.List;28import java.util.concurrent.locks.ReadWriteLock;29import java.util.concurrent.locks.ReentrantReadWriteLock;30import nsk.share.TestBug;31import nsk.share.TestFailure;32import nsk.share.gc.gp.string.RandomStringProducer;33import nsk.share.test.ExecutionController;34import nsk.share.test.LocalRandom;3536class StringGenerator implements Runnable {3738private final RandomStringProducer gp;39private final List<String> stringsToIntern;40private final int threadNumber;41private final int numberOfActions;42private final int maxStringSize;43private final StringInternSyncWithGC base;44private static final ReadWriteLock RWLOCK = new ReentrantReadWriteLock();4546public StringGenerator(int threadId, StringInternSyncWithGC base) {47this.base = base;48threadNumber = threadId;49stringsToIntern = base.getStringsToIntern();50numberOfActions = base.getNumberOfThreads() > 4 ? base.getNumberOfThreads() : 4;51gp = base.getGarbageProducer();52maxStringSize = base.getMaxStringSize();53}5455/* This field is public just to be not optimized */56public String copy;5758@Override59public void run() {60ExecutionController stresser = base.getExecController();61try {62RWLOCK.readLock().lock();63Object[] refToInterned = new Object[stringsToIntern.size()];64for (int i = 0; i < stringsToIntern.size(); i++) {65if (!stresser.continueExecution()) {66return;67}68int index = LocalRandom.nextInt(stringsToIntern.size());69String str = stringsToIntern.get(index);70int action = LocalRandom.nextInt(numberOfActions);7172/* We want to provoke a lot of collections for each interned copy73* so map should be "sparse".74*/75copy = new String(str);76switch (action) {77case 0:78refToInterned[index] = copy.intern();79break;80case 1:81refToInterned[index] = new WeakReference(copy.intern());82break;83case 2:84refToInterned[index] = new SoftReference(copy.intern());85break;86default:87refToInterned[index] = null;88break;89}90}91for (int index = 0; index < stringsToIntern.size(); index++) {92verify(refToInterned[index], stringsToIntern.get(index));93}94} finally {95RWLOCK.readLock().unlock();96}9798if (threadNumber == 0) {99try {100RWLOCK.writeLock().lock();101for (int index = 0; index < stringsToIntern.size(); index++) {102stringsToIntern.set(index, gp.create(maxStringSize).intern());103}104} finally {105RWLOCK.writeLock().unlock();106}107}108}109110/*111* Verify that all exist interned strings in a map112* a same objects.113*/114private void verify(Object obj, String str) {115if (obj == null) {116return;117}118if (obj instanceof Reference) {119obj = ((Reference) obj).get();120if (obj == null) {121return;122}123}124if (!(obj instanceof String)) {125throw new TestBug("Expected String. Find :" + obj.getClass());126}127String interned = (String) obj;128if (!interned.equals(str)) {129throw new TestFailure("Interned not equals to original string.");130}131if (obj != str.intern()) {132throw new TestFailure("Interned not same as original string.");133}134}135}136137138