I am trying to create multiple threads in a jenkins pipeline script. So, I took simple example as below. But it not working. Could you please let me know?
In the below example, jobMap contains a key as a string and value as List of Strings. When I just display the list, the values printed properly, but when I used 3 different ways to create threads and thus to display, it is not working.
for ( item in jobMap )
{
def jobList = jobMap.get(item.key);
**// The following loop is printing the values**
for (jobb in jobList)
{
echo "${jobb}"
}
// Thread Implementation1:
Thread.start
{
for (jobb in jobList)
{
echo "${jobb}"
}
}
// Thread Implementation2:
def t = new Thread({ echo 'hello' } as Runnable)
t.start() ;
t.join();
// Thread Implementation3:
t1 = new Thread( new TestMultiThreadSleep(jobList));
t1.start();
}
class TestMultiThreadSleep implements Runnable {
String jobs;
public TestMultiThreadSleep(List jobs) {
this.jobs = jobs;
}
#Override
public void run()
{
echo "coming here"
for (jobb in jobs)
{
echo "${jobb}"
}
}
}
Jenkins has special step - parallel(). In this step you can build another jobs or call Pipeline code.
It's best to think of Pipeline code as a dialect or subset of Groovy.
The CPS transformer ("continuation-passing style") in the workflow script engine turns the Groovy code into something that can be interpreted in a serialized form, passed between different JVMs, etc.
You can probably imagine that this will not work at all well with threads.
If you need threads, you'll have to work within a #NonCPS annotated class or function. This class or function must not call any CPS groovy code - so it can't invoke closures, access the workflow script context, etc.
That's why using the parallel step is preferable.
Related
This is a scala code I'm trying to write for processing a function multiple times concurrently with two different parameters. However, I notice that the functions are being executed one by one and not both at same time.
class Method1 extends Thread {
override def run(): Unit ={
println("Hello, Current running is Thread No. " + Thread.currentThread().getName )
Function("Parameter 1")
Function("Parameter 2")
}
}
object Obj extends App {
for (x <- 1 to 4){
val th1 = new Method1()
th1.setName(x.toString)
th1.start()
}
}
val a = Array("Justanormalarray")
Obj.main(a)
How to achieve this? Sorry for being dumb but all tutorials I seen only explains a very basic level that multithreading can be achieved by extending thread class or by using runnable interface, but doesn't seem to clear this up (i.e. how to actually execute multiple stuff at same time)
Inside a spock test we want to create a resource and make sure its disposed correctly regardless of the outcome of the test result.
We tried the approach below. But spock is not executing tests when the test code is wrapped inside a closure.
import spock.lang.Specification
class ExampleSpec extends Specification {
def wrapperFunction(Closure cl) {
try {
cl()
} finally {
// do custom stuff
}
}
def "test wrapped in closure"() {
wrapperFunction {
expect:
1 == 1
println "will not execute!"
}
}
}
What is the best approach on creating and disposing a resource inside a spock test.
setup() and cleanup() are not viable solutions since creating and disposing should be possible at arbitrary points inside the feature method.
You can use setup and cleanup block inside of the test case (feature method) like this:
class ReleaseResourcesSpec extends Specification {
void 'Resources are released'() {
setup:
def stream = new FileInputStream('/etc/hosts')
when:
throw new IllegalStateException('test')
then:
true
cleanup:
stream.close()
println 'stream was closed'
}
}
Code from the cleanup block is always executed although the test fails or if there is any exception. See the result of the above example:
So it is similar to setup() and cleanup() methods but in this case you can have different setup and clean up code for each feature method.
I am trying the execute the below code in which four threads are running.
Each thread trying to add the one character to mylist. After each run, there should be 4 elements in the list in any order. But, when this code is run in jenkin console, getting each time different number of elements. i.e, [A, B, Null], [C,null,D],[A,B,C,D].
It seem like some synchronization issue due to multi tasking. I have tried adding method add element to list using synchronize keyword but that didn't help.
class Globals {
static def mylist=[]
}
class TestMultiThreadExecution implements Runnable
{
String name;
public TestMultiThreadExecution(String name) {
this.name = name;
}
//#Override
public void run() {
println "${name} Step 1"
Globals.mylist.push("${name}")
}
}
Globals.mylist.clear()
Thread thread1 = new Thread(new TestMultiThreadExecution("A"));
thread1.start();
Thread thread2 = new Thread(new TestMultiThreadExecution("B"));
thread2.start();
Thread thread3 = new Thread(new TestMultiThreadExecution("C"));
thread3.start();
Thread thread4 = new Thread(new TestMultiThreadExecution("D"));
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
println Globals.mylist
It is because, list is being concurrently accessed and modified by 4 threads.
You can fix it by changing list type to CopyOnWriteArrayList as shown below.
So, the only change in the above code is to change list type in the Globals class. Here is the changed code snippet.
import java.util.concurrent.CopyOnWriteArrayList
class Globals {
static def mylist = [] as CopyOnWriteArrayList
}
By the, it would be lot easier in groovy to deal with threads. May be you can refer a sample
I am learning Scala multi-thread programming, and write a simple program through referring a tutorial:
object ThreadSleep extends App {
def thread(body: =>Unit): Thread = {
val t = new Thread {
override def run() = body
}
t.start()
t
}
val t = thread{println("New Therad")}
t.join
}
I can't understand why use {} in new Thread {} statement. I think it should be new Thread or new Thread(). How can I understand this syntax?
This question is not completely duplicated to this one, because the point of my question is about the syntax of "new {}".
This is a shortcut for
new Thread() { ... }
This is called anonymous class and it works just like in JAVA:
You are here creating a new thread, with an overriden run method. This is useful because you don't have to create a special class if you only use it once.
Needs confirmation but you can override, add, redefine every method or attribute you want.
See here for more details: https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
By writing new Thread{} your creating an anonymous subclass of Thread where you're overriding the run method. Normally, you'd prefer to create a subclass of Runnable and create a thread with it instead of subclassing Thread
val r = new Runnable{ override def run { body } }
new Thread(r).start
This is usually sematincally more correct, since you'd want to subclass Thread only if you were specializing the Thread class more, for example with an AbortableThread. If you just want to run a task on a thread, the Runnable approach is more adequate.
I have the following Groovy code:
abstract class Actor extends Script {
synchronized void proceed() {
this.notify()
}
synchronized void pause() {
wait()
}
}
class MyActor extends Actor {
def run() {
println "hi"
pause()
println "hi again"
}
}
def theactor = new MyActor()
theactor.run()
theactor.proceed()
When I run the code, I want the code to output "hi" and "hi again". Instead, it just stops at "hi" and gets stuck on the pause() function. Any idea on how I could continue the program?
As Brian says, multithreading and concurrency is a huge area, and it is easier to get it wrong, than it is to get it right...
To get your code working, you'd need to have something like this:
abstract class Actor implements Runnable {
synchronized void proceed() { notify() }
synchronized void pause() { wait() }
}
class MyActor extends Actor {
void run() {
println "hi"
pause()
println "hi again"
}
}
def theactor = new MyActor() // Create an instance of MyActor
def actorThread = new Thread( theactor ) // Create a Thread to run this instance in
actorThread.start() // Thread.start() will call MyActor.run()
Thread.sleep( 500 ) // Make the main thread go to sleep for some time so we know the actor class is waiting
theactor.proceed() // Then call proceed on the actor
actorThread.join() // Wait for the thread containing theactor to terminate
However, if you are using Groovy, I would seriously consider using a framework like Gpars which brings concurrency to Groovy and is written by people who really know their stuff. I can't think of anything that llows this sort of arbitrary pausing of code however... Maybe you could design your code to fit one of their usage patterns instead?
Threading is a big topic and there are libraries in Java to do many common things without working with the Thread API directly. One simple example for 'Fire and Forget' is Timer.
But to answer your immediate question; another thread needs to notify your thread to continue. See the docs on wait()
Causes current thread to wait until another thread invokes the
notify() method or the notifyAll() method for this object. In other
words, this method behaves exactly as if it simply performs the call
wait(0).
One simple 'fix' is to just add a fixed duration to your wait call just to continue with your exploration. I would suggest the book 'Java Concurrency in Practice'.
synchronized void pause() {
//wait 5 seconds before resuming.
wait(5000)
}