In the traditional synchronous development model, when we call a function, the data is passed in through the parameters of the function, and the final calculation result is returned through the return value of the function. However, in the multi-threaded asynchronous development mode, the transmission and return of data are very different from the synchronous development mode. Since the running and ending of threads are unpredictable, when transferring and returning data, data cannot be returned through function parameters and return statements like functions. This article introduces several methods for passing data to threads for the above reasons. In the next article, we will introduce methods of returning data from threads.
If you want to take it first, you must give it first. Generally, when using threads, you need some initialization data, and then the thread uses these data to process and return the results. The first thing to do in this process is to pass data to the thread.
1. Pass data through the constructor method <BR>When creating a thread, you must create an instance of the Thread class or its subclass. Therefore, it is not difficult for us to think of passing data into the thread through the constructor method of the thread class before calling the start method. And save the incoming data using class variables for use by the thread (actually used in the run method). The following code demonstrates how to pass data through the constructor:
Copy the code code as follows:
package mythread;
public class MyThread1 extends Thread
{
private String name;
public MyThread1(String name)
{
this.name = name;
}
public void run()
{
System.out.println("hello " + name);
}
public static void main(String[] args)
{
Thread thread = new MyThread1("world");
thread.start();
}
}
Since this method transfers data while creating the thread object, the data is already in place before the thread runs, so that the data will not be passed in after the thread runs. If you want to pass more complex data, you can use data structures such as collections and classes. Although it is safer to use the constructor method to transfer data, it will cause a lot of inconvenience if there is a lot of data to be transferred. Since Java does not have default parameters, if you want to achieve effects similar to default parameters, you have to use overloading. This not only makes the constructor itself too complex, but also greatly increases the number of constructors. Therefore, to avoid this situation, pass data through class methods or class variables.
2. Pass data through variables and methods <BR>There are generally two opportunities to pass data into an object. The first opportunity is to pass the data in through the constructor method when creating the object, and the other opportunity is to define a series of data in the class. Public methods or variables (also called fields). Then after creating the object, assign values one by one through object instances. The following code is a modification of the MyThread1 class, using a setName method to set the name variable:
Copy the code code as follows:
package mythread;
public class MyThread2 implements Runnable
{
private String name;
public void setName(String name)
{
this.name = name;
}
public void run()
{
System.out.println("hello " + name);
}
public static void main(String[] args)
{
MyThread2 myThread = new MyThread2();
myThread.setName("world");
Thread thread = new Thread(myThread);
thread.start();
}
}
3. Pass data through callback functions <BR>The two methods of passing data to threads discussed above are the most commonly used. But both methods actively pass data into the thread class in the main method. For threads, this data is passively received. However, in some applications it is necessary to obtain data dynamically while the thread is running. For example, three random numbers are generated in the run method of the following code, and then the sum of these three random numbers is calculated through the process method of the Work class, and Return the result through the value of the Data class. As can be seen from this example, three random numbers must be obtained before returning value. In other words, this value cannot be passed into the thread class in advance.
Copy the code code as follows:
package mythread;
class Data
{
public int value = 0;
}
class work
{
public void process(Data data, Integer numbers)
{
for (int n : numbers)
{
data.value += n;
}
}
}
public class MyThread3 extends Thread
{
private work work;
public MyThread3(Work work)
{
this.work = work;
}
public void run()
{
java.util.Random random = new java.util.Random();
Data data = new Data();
int n1 = random.nextInt(1000);
int n2 = random.nextInt(2000);
int n3 = random.nextInt(3000);
work.process(data, n1, n2, n3); // Use callback function
System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+"
+ String.valueOf(n3) + "=" + data.value);
}
public static void main(String[] args)
{
Thread thread = new MyThread3(new Work());
thread.start();
}
}
The process method in the above code is called the callback function. In essence, callback functions are event functions. In Windows API, callback functions are often used to interact with data between the program calling the API. Therefore, the process of calling the callback function is the original process of triggering the event. In this example, calling the process method to obtain data is equivalent to triggering an event in the run method.