8303702: Provide ThreadFactory to create platform/virtual threads for com/sun/jdi tests

Reviewed-by: cjplummer, sspitsyn
This commit is contained in:
Leonid Mesnik 2023-03-09 15:44:03 +00:00
parent 4655b790d0
commit cdcf5c1ed8
13 changed files with 86 additions and 96 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,34 +50,27 @@ class ClassesByName2Targ {
System.out.println("Howdy!"); System.out.println("Howdy!");
try { try {
Thread zero = new Thread ("ZERO") { Thread zero = TestScaffold.newThread (() -> {
public void run () {
System.setProperty("java.awt.headless", "true"); System.setProperty("java.awt.headless", "true");
java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit(); java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
}, "ZERO");
} Thread one = TestScaffold.newThread (() -> {
};
Thread one = new Thread ("ONE") {
public void run () {
try { try {
java.security.KeyPairGenerator keyGen = java.security.KeyPairGenerator keyGen =
java.security.KeyPairGenerator.getInstance("DSA", "SUN"); java.security.KeyPairGenerator.getInstance("DSA", "SUN");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }, "ONE");
};
Thread two = new Thread ("TWO") { Thread two = TestScaffold.newThread (() -> {
public void run () {
try { try {
String s = String.format("%02x", 0xff); String s = String.format("%02x", 0xff);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }, "TWO");
};
two.start(); two.start();
one.start(); one.start();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -74,8 +74,8 @@ class DeferredStepTestTarg {
jj1 obj1 = new jj1(); jj1 obj1 = new jj1();
jj2 obj2 = new jj2(); jj2 obj2 = new jj2();
new Thread(obj1, "jj1").start(); TestScaffold.newThread(obj1, "jj1").start();
new Thread(obj2, "jj2").start(); TestScaffold.newThread(obj2, "jj2").start();
} }
} }

View File

@ -843,21 +843,18 @@ abstract class EATestCaseBaseTarget extends EATestCaseBaseShared implements Runn
public static void staticSetUp() { public static void staticSetUp() {
inflatedLock = new XYVal(1, 1); inflatedLock = new XYVal(1, 1);
synchronized (inflatedLock) { synchronized (inflatedLock) {
inflatorThread = new Thread("Lock Inflator (test thread)") { inflatorThread = TestScaffold.newThread(() -> {
@Override synchronized (inflatedLock) {
public void run() { inflatedLockIsPermanentlyInflated = true;
synchronized (inflatedLock) { inflatedLock.notify(); // main thread
inflatedLockIsPermanentlyInflated = true; while (true) {
inflatedLock.notify(); // main thread try {
while (true) { // calling wait() on a monitor will cause inflation into a heavy monitor
try { inflatedLock.wait();
// calling wait() on a monitor will cause inflation into a heavy monitor } catch (InterruptedException e) { /* ignored */ }
inflatedLock.wait();
} catch (InterruptedException e) { /* ignored */ }
}
} }
} }
}; }, "Lock Inflator (test thread)");
inflatorThread.setDaemon(true); inflatorThread.setDaemon(true);
inflatorThread.start(); inflatorThread.start();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -47,7 +47,7 @@ class InterruptHangTarg {
public static void main(String[] args){ public static void main(String[] args){
int answer = 0; int answer = 0;
System.out.println("Howdy!"); System.out.println("Howdy!");
Interruptor interruptorThread = new Interruptor(Thread.currentThread()); Thread interruptorThread = TestScaffold.newThread(new Interruptor(Thread.currentThread()));
synchronized(sync) { synchronized(sync) {
interruptorThread.start(); interruptorThread.start();
@ -75,7 +75,7 @@ class InterruptHangTarg {
} }
} }
class Interruptor extends Thread { class Interruptor implements Runnable {
Thread interruptee; Thread interruptee;
Interruptor(Thread interruptee) { Interruptor(Thread interruptee) {
this.interruptee = interruptee; this.interruptee = interruptee;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,7 +46,7 @@ import java.util.*;
* which loop, hitting a bkpt in each iteration. * which loop, hitting a bkpt in each iteration.
* *
*/ */
class InvokeHangTarg extends Thread { class InvokeHangTarg implements Runnable {
static boolean one = false; static boolean one = false;
static String name1 = "Thread 1"; static String name1 = "Thread 1";
static String name2 = "Thread 2"; static String name2 = "Thread 2";
@ -54,8 +54,8 @@ class InvokeHangTarg extends Thread {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Howdy!"); System.out.println("Howdy!");
InvokeHangTarg t1 = new InvokeHangTarg(name1); Thread t1 = TestScaffold.newThread(new InvokeHangTarg(), name1);
InvokeHangTarg t2 = new InvokeHangTarg(name2); Thread t2 = TestScaffold.newThread(new InvokeHangTarg(), name2);
t1.start(); t1.start();
t2.start(); t2.start();
@ -81,12 +81,8 @@ class InvokeHangTarg extends Thread {
return s; return s;
} }
public InvokeHangTarg(String name) {
super(name);
}
public void run() { public void run() {
if (getName().equals(name1)) { if (Thread.currentThread().getName().equals(name1)) {
run1(); run1();
} else { } else {
run2(); run2();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,11 +39,11 @@ class JdbLockTestTarg {
static String jj = "jj"; static String jj = "jj";
public static void main(String args[]) { public static void main(String args[]) {
synchronized(jj) { synchronized(jj) {
sleeper xx = new sleeper(); Thread xx = TestScaffold.newThread(new Sleeper());
xx.start(); xx.start();
// Give the sleeper a chance to run and get to // Give the sleeper a chance to run and get to
// the synchronized statement. // the synchronized statement.
while(sleeper.started == 0) { while(Sleeper.started == 0) {
try { try {
Thread.sleep(100); Thread.sleep(100);
} catch(InterruptedException ee) { } catch(InterruptedException ee) {
@ -55,7 +55,7 @@ class JdbLockTestTarg {
} }
} }
class sleeper extends Thread { class Sleeper implements Runnable {
public static int started = 0; public static int started = 0;
public void run() { public void run() {
started = 1; started = 1;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,16 +48,19 @@ class JdbStopThreadidTestTarg {
private static void test() { private static void test() {
JdbStopThreadidTestTarg test = new JdbStopThreadidTestTarg(); JdbStopThreadidTestTarg test = new JdbStopThreadidTestTarg();
MyThread myThread1 = test.new MyThread("MYTHREAD-1"); MyTask myTask1 = test.new MyTask();
MyThread myThread2 = test.new MyThread("MYTHREAD-2"); MyTask myTask2 = test.new MyTask();
MyThread myThread3 = test.new MyThread("MYTHREAD-3"); MyTask myTask3 = test.new MyTask();
Thread myThread1 = TestScaffold.newThread(myTask1, "MYTHREAD-1");
Thread myThread2 = TestScaffold.newThread(myTask2, "MYTHREAD-2");
Thread myThread3 = TestScaffold.newThread(myTask3, "MYTHREAD-3");
synchronized (lockObj) { synchronized (lockObj) {
myThread1.start(); myThread1.start();
myThread2.start(); myThread2.start();
myThread3.start(); myThread3.start();
// Wait for all threads to have started. Note they all block on lockObj after starting. // Wait for all threads to have started. Note they all block on lockObj after starting.
while (!myThread1.started || !myThread2.started || !myThread3.started) { while (!myTask1.started || !myTask2.started || ! myTask3.started) {
try { try {
Thread.sleep(50); Thread.sleep(50);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -83,13 +86,9 @@ class JdbStopThreadidTestTarg {
System.out.println(obj); System.out.println(obj);
} }
class MyThread extends Thread { class MyTask implements Runnable {
volatile boolean started = false; volatile boolean started = false;
public MyThread(String name) {
super(name);
}
public void run() { public void run() {
started = true; started = true;
synchronized (JdbStopThreadidTestTarg.lockObj) { synchronized (JdbStopThreadidTestTarg.lockObj) {
@ -112,8 +111,8 @@ public class JdbStopThreadidTest extends JdbTest {
} }
private static final String DEBUGGEE_CLASS = JdbStopThreadidTestTarg.class.getName(); private static final String DEBUGGEE_CLASS = JdbStopThreadidTestTarg.class.getName();
private static final String DEBUGGEE_THREAD_CLASS = JdbStopThreadidTestTarg.class.getName() + "$MyThread"; private static final String DEBUGGEE_THREAD_CLASS = JdbStopThreadidTestTarg.class.getName() + "$MyTask";
private static Pattern threadidPattern = Pattern.compile("MyThread\\)(\\S+)\\s+MYTHREAD-2"); private static Pattern threadidPattern = Pattern.compile("Thread\\)(\\S+)\\s+MYTHREAD-2");
@Override @Override
protected void runCases() { protected void runCases() {
@ -136,7 +135,7 @@ public class JdbStopThreadidTest extends JdbTest {
// Continue until MYTHREAD-2 breakpoint is hit. If we hit any other breakpoint before // Continue until MYTHREAD-2 breakpoint is hit. If we hit any other breakpoint before
// then (we aren't suppose to), then this test will fail. // then (we aren't suppose to), then this test will fail.
jdb.command(JdbCommand.cont().waitForPrompt("Breakpoint hit: \"thread=MYTHREAD-2\", \\S+MyThread.brkMethod", true)); jdb.command(JdbCommand.cont().waitForPrompt("Breakpoint hit: \"thread=MYTHREAD-2\", \\S+MyTask.brkMethod", true));
// Continue until the application exits. Once again, hitting a breakpoint will cause // Continue until the application exits. Once again, hitting a breakpoint will cause
// a failure because we are not suppose to hit one. // a failure because we are not suppose to hit one.
jdb.contToExit(1); jdb.contToExit(1);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -61,7 +61,7 @@ class MonitorEventTestTarg {
endingMonitor = new Object(); endingMonitor = new Object();
startingMonitor = new Object(); startingMonitor = new Object();
myThread t1 = new myThread(); Thread t1 = TestScaffold.newThread(new MyTask());
foo(); foo();
aboutEnterLock = false; aboutEnterLock = false;
@ -96,7 +96,7 @@ class MonitorEventTestTarg {
} }
} }
class myThread extends Thread { class MyTask implements Runnable {
public void run() { public void run() {
synchronized(MonitorEventTestTarg.startingMonitor) { synchronized(MonitorEventTestTarg.startingMonitor) {
MonitorEventTestTarg.startingMonitor.notify(); MonitorEventTestTarg.startingMonitor.notify();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -101,7 +101,7 @@ public class PopAsynchronousTest extends TestScaffold {
/********** test assist **********/ /********** test assist **********/
class HarassThread extends Thread { class HarassThread implements Runnable {
public void run() { public void run() {
int harassCount = 0; int harassCount = 0;
try { try {
@ -186,7 +186,7 @@ public class PopAsynchronousTest extends TestScaffold {
/* /*
* start popping wildly away * start popping wildly away
*/ */
(new HarassThread()).start(); TestScaffold.newThread(new HarassThread()).start();
/* /*
* resume the target listening for events * resume the target listening for events

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,18 +37,14 @@ import com.sun.jdi.request.*;
import java.util.*; import java.util.*;
class ResumeOneThreadTarg extends Thread { class ResumeOneThreadTarg implements Runnable {
static String name1 = "Thread 1"; static String name1 = "Thread 1";
static String name2 = "Thread 2"; static String name2 = "Thread 2";
public ResumeOneThreadTarg(String name) {
super(name);
}
public static void main(String[] args) { public static void main(String[] args) {
System.out.println(" Debuggee: Howdy!"); System.out.println(" Debuggee: Howdy!");
ResumeOneThreadTarg t1 = new ResumeOneThreadTarg(name1); Thread t1 = TestScaffold.newThread(new ResumeOneThreadTarg(), name1);
ResumeOneThreadTarg t2 = new ResumeOneThreadTarg(name2); Thread t2 = TestScaffold.newThread(new ResumeOneThreadTarg(), name2);
// Force these threads to be non-daemon threads, even when the debuggee // Force these threads to be non-daemon threads, even when the debuggee
// is being run as a vthread. See JDK-8283796. // is being run as a vthread. See JDK-8283796.
t1.setDaemon(false); t1.setDaemon(false);
@ -59,7 +55,7 @@ class ResumeOneThreadTarg extends Thread {
// This just starts two threads. Each runs to a bkpt. // This just starts two threads. Each runs to a bkpt.
public void run() { public void run() {
if (getName().equals(name1)) { if (Thread.currentThread().getName().equals(name1)) {
run1(); run1();
} else { } else {
run2(); run2();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -43,26 +43,22 @@ import java.util.*;
* which loop, hitting a bkpt in each iteration. * which loop, hitting a bkpt in each iteration.
* *
*/ */
class SimulResumerTarg extends Thread { class SimulResumerTarg implements Runnable {
static boolean one = false; static boolean one = false;
static String name1 = "Thread 1"; static String name1 = "Thread 1";
static String name2 = "Thread 2"; static String name2 = "Thread 2";
static int count = 10000; static int count = 10000;
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Howdy!"); System.out.println("Howdy!");
SimulResumerTarg t1 = new SimulResumerTarg(name1); Thread t1 = TestScaffold.newThread(new SimulResumerTarg(), name1);
SimulResumerTarg t2 = new SimulResumerTarg(name2); Thread t2 = TestScaffold.newThread(new SimulResumerTarg(), name2);
t1.start(); t1.start();
t2.start(); t2.start();
} }
public SimulResumerTarg(String name) {
super(name);
}
public void run() { public void run() {
if (getName().equals(name1)) { if (Thread.currentThread().getName().equals(name1)) {
run1(); run1();
} else { } else {
run2(); run2();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ import com.sun.jdi.event.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
import java.util.concurrent.ThreadFactory;
/** /**
* Framework used by all JDI regression tests * Framework used by all JDI regression tests
@ -964,6 +965,8 @@ abstract public class TestScaffold extends TargetAdapter {
vmDisconnected = true; vmDisconnected = true;
} }
private static ThreadFactory threadFactory = r -> new Thread(r);
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
String wrapper = args[0]; String wrapper = args[0];
String className = args[1]; String className = args[1];
@ -974,9 +977,10 @@ abstract public class TestScaffold extends TargetAdapter {
mainMethod.setAccessible(true); mainMethod.setAccessible(true);
if (wrapper.equals("Virtual")) { if (wrapper.equals("Virtual")) {
threadFactory = r -> newVirtualThread(r);
MainThreadGroup tg = new MainThreadGroup(); MainThreadGroup tg = new MainThreadGroup();
// TODO fix to set virtual scheduler group when become available // TODO fix to set virtual scheduler group when become available
Thread vthread = startVirtualThread(() -> { Thread vthread = newVirtualThread(() -> {
try { try {
mainMethod.invoke(null, new Object[] { classArgs }); mainMethod.invoke(null, new Object[] { classArgs });
} catch (InvocationTargetException e) { } catch (InvocationTargetException e) {
@ -987,6 +991,7 @@ abstract public class TestScaffold extends TargetAdapter {
}); });
Thread.currentThread().setName(OLD_MAIN_THREAD_NAME); Thread.currentThread().setName(OLD_MAIN_THREAD_NAME);
vthread.setName("main"); vthread.setName("main");
vthread.start();
vthread.join(); vthread.join();
} else if (wrapper.equals("Kernel")) { } else if (wrapper.equals("Kernel")) {
MainThreadGroup tg = new MainThreadGroup(); MainThreadGroup tg = new MainThreadGroup();
@ -1024,16 +1029,27 @@ abstract public class TestScaffold extends TargetAdapter {
Throwable uncaughtThrowable = null; Throwable uncaughtThrowable = null;
} }
static Thread startVirtualThread(Runnable task) { // Need to use reflection while virtual threads --enable-preview feature
private static Thread newVirtualThread(Runnable task) {
try { try {
Object builder = Thread.class.getMethod("ofVirtual").invoke(null); Object builder = Thread.class.getMethod("ofVirtual").invoke(null);
Class<?> clazz = Class.forName("java.lang.Thread$Builder"); Class<?> clazz = Class.forName("java.lang.Thread$Builder");
java.lang.reflect.Method start = clazz.getMethod("start", Runnable.class); java.lang.reflect.Method unstarted = clazz.getMethod("unstarted", Runnable.class);
return (Thread) start.invoke(builder, task); return (Thread) unstarted.invoke(builder, task);
} catch (RuntimeException | Error e) { } catch (RuntimeException | Error e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
public static Thread newThread(Runnable task) {
return threadFactory.newThread(task);
}
public static Thread newThread(Runnable task, String name) {
Thread t = newThread(task);
t.setName(name);
return t;
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -42,7 +42,7 @@ import java.util.*;
* which loop, hitting a bkpt in each iteration. * which loop, hitting a bkpt in each iteration.
* *
*/ */
class TwoThreadsTarg extends Thread { class TwoThreadsTarg implements Runnable {
static boolean one = false; static boolean one = false;
static String name1 = "Thread 1"; static String name1 = "Thread 1";
static String name2 = "Thread 2"; static String name2 = "Thread 2";
@ -50,19 +50,16 @@ class TwoThreadsTarg extends Thread {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Howdy!"); System.out.println("Howdy!");
TwoThreadsTarg t1 = new TwoThreadsTarg(name1); Thread t1 = TestScaffold.newThread(new TwoThreadsTarg(), name1);
TwoThreadsTarg t2 = new TwoThreadsTarg(name2); Thread t2 = TestScaffold.newThread(new TwoThreadsTarg(), name2);
t1.start(); t1.start();
t2.start(); t2.start();
} }
public TwoThreadsTarg(String name) {
super(name);
}
public void run() { public void run() {
if (getName().equals(name1)) { if (Thread.currentThread().getName().equals(name1)) {
run1(); run1();
} else { } else {
run2(); run2();