Threads and processes
There will be multiple processes in the operating system: these processes include system processes and user processes.
System process refers to the process established within the operating system.
User process refers to the process established by the user program.
Difference between process and thread:
1. No memory is shared between processes. Processes run in independent memory space.
2. Threads can share the memory space allocated by the system to this process.
3. Threads can not only share the memory of the process, but also have their own memory space. This space is called thread stack, which is allocated by the system when creating threads. It is mainly used to save the data used inside threads.
start and run
Java encapsulates all the functions necessary for threads through the Thread class.
The thread execution function is the run() method
Thread also has a start() method. This method is to establish a thread. After calling the strat() method, if the thread is established successfully, the program will automatically call the run() method of thread class.
Note: for the strat() method, if the thread is established successfully, the run method will be called automatically. The execution thread must call start() to join the scheduler, which is not necessarily executed immediately. The system arranges scheduling and allocation for execution. Calling run() directly does not start multithreading, but ordinary method calls
Any inheriting Thread class can create a Thread by calling the start method. If you want to run the execution function of your own Thread, you need to override the run() method of Thread class.
/** * Multithreading test * The first method inherits Thread * Multiple execution results are different, and two threads execute at the same time * strat()Method does not guarantee immediate operation, which is determined by the CPU */ public class ThreadTest extends Thread { @Override public void run(){ for (int i = 0;i<=10;i++){ System.out.println(i); } } public void run2(){ for (int i = 0;i<=10;i++){ System.out.println(i+"run2............."); } } //Explicit nonparametric construction ThreadTest(){ System.out.println("Created ThreadTest"); } public static void main(String[] args) { ThreadTest threadTest = new ThreadTest(); threadTest.start(); threadTest.run2(); } }
Picture download case
/** * Picture download case */ public class ThreadTestPictureDown { /** * Download method * @param url * @param name */ public void download(String url,String name){ try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("illegal URL,Download failed"); } } }
In essence, it is no different from the previous cases. The only thing to pay attention to is the tool class FileUtils, which can download files.
public class TDownLoad extends Thread{ private String url; private String name; public TDownLoad(String url,String name){ this.url = url; this.name = name; } @Override public void run() { ThreadTestPictureDown threadTestPictureDown = new ThreadTestPictureDown(); threadTestPictureDown.download(url,name); System.out.println("download"+name+"Picture complete"); } public static void main(String[] args) { TDownLoad t1 = new TDownLoad("https://t7.baidu.com/it/u=1819248061,230866778&fm=193&f=GIF","t1.jpg"); TDownLoad t2 = new TDownLoad("https://t7.baidu.com/it/u=4036010509,3445021118&fm=193&f=GIF","t2.jpg"); TDownLoad t3 = new TDownLoad("https://t7.baidu.com/it/u=963301259,1982396977&fm=193&f=GIF","t3.jpg"); t1.start(); t2.start(); t3.start(); } }
Print result picture 3, picture 1, picture 2
Thread and Runnable
Thread class can be implemented by inheriting thread class and Runnable interface. In fact, thread class also implements Runnable interface. Thread is more powerful as an implementation class, and there is only one run method in the source code of Runnable interface. However, only single inheritance can be implemented in Java, but multiple interfaces can be implemented. Therefore, pay attention to reasonable selection when using.
When inheriting the Thread class, if the class is not named, the default Thread name Thread-N will be automatically used. N represents the order in which threads are established and is a non repeating integer.
Note: when creating a Thread class by implementing the Runnable interface, you still need to create a Thread object, pass the Thread class as a parameter into the Thread object, and call the start method. Calling the run method directly does not start the Thread, but still starts the run method in the main Thread.
You can multiple agents at this time. The following small case of ticket grabbing can be seen.
public class ThreadTest01 implements Runnable{ @Override public void run(){ for (int i = 0;i<=10;i++){ System.out.println(i); } } public void run2(){ for (int i = 0;i<=10;i++){ System.out.println(i+"run2............."); } } //Explicit nonparametric construction ThreadTest01(){ System.out.println("Created ThreadTest"); } public static void main(String[] args) { ThreadTest01 threadTest01 = new ThreadTest01(); new Thread(threadTest01).start(); threadTest01.run2(); } }
Small case of ticket grabbing
public class ThreadTest01 implements Runnable{ private int tickNums = 99; @Override public void run(){ while (true){ if (tickNums<0){ break; } System.out.println(Thread.currentThread().getName()+"--->"+tickNums--); } } //Explicit nonparametric construction ThreadTest01(){ System.out.println("Created ThreadTest"); } public static void main(String[] args) { ThreadTest01 threadTest01 = new ThreadTest01(); //Multiple agents, adding name discrimination new Thread(threadTest01,"thread01").start(); new Thread(threadTest01,"thread02").start(); new Thread(threadTest01,"thread03").start(); } }
But this is problematic. In reality, if there is a delay in the network, there may be a negative problem. Not yet. Let's add thread sleep for 200ms to simulate this situation.
@Override public void run(){ while (true){ if (tickNums<0){ break; } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--->"+tickNums--); } }
In this way, negative numbers will appear when printing on the console. At this time, it is also a concurrency problem, and thread safety needs to be ensured in the follow-up. The runable interface can share resources, but it can also cause the problem of resource grabbing.