Thread instance analysis - comprehensive application of threads (wizard thread, multithreading, interrupt, communication) [java]

Keywords: PHP Java Interview

Java learning punch in: day 28

Java cultivation program (punch in day 28)

Content management: today's sharing is mainly about three threads. Later, we will consolidate the File class

Thread instance analysis

Q1: application of threads and wizard threads

Title Content:

Create a thread containing instance variable i. after the thread starts, first create and start a sprite thread, and then cycle and accumulate 1 for variable i until the value of i is equal to Integer.MAX_VALUE. The sprite thread outputs the value of i every 1s

problem analysis

This topic is very simple. It directly tells the content of run, that is, to create a wizard thread. According to previous experience, we can create it in the construction method, but we can't do this because the construction method can only create one thread, so it looks more convenient

Here, the second thread is created directly in the run method. It's just a little troublesome. It's better to use reference, but here only let you create a spirit thread. Therefore, use the single instance mode to create a self-contained object and create a thread when it is not empty

package ThreadDemo;

public class ThreadDemo implements Runnable{
	private static ThreadDemo dem = new ThreadDemo();
	private int i = 0;
	Thread t2 = null;
	@Override
	public void run() {
		if(t2 == null)//Use single instance mode to create thread objects
		{
			t2 = new Thread(dem);//This code can only be executed once
			t2.setDaemon(true);
			t2.start();
		}
		for(;i <= Integer.MAX_VALUE;i++)
		{
			if(Thread.currentThread().isDaemon())
			{
				System.out.println(Thread.currentThread().getName()+"i = " + i);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static void main(String[] args) {
		Thread t1 = new Thread(dem);
		t1.start();
	}
}

Reference is used here. If reference is not used, there must be an object. The object in the previous consumer is the instance q of the Queue, and this in the construction method is the object q referred to, so the object is locked during execution. I used it directly without creating an object before here, resulting in confusion

Output results

Thread-1i = 2541
Thread-1i = 521692808
Thread-1i = 1039199618
Thread-1i = 1553714050
Thread-1i = 2086683371

The thread name is output here to check whether only one sprite thread is created

Q2: application of multithreading and interrput

Title Content:

Two threads t1 and t2 are created. After thread t1 is created, it enters into deep sleep with a sleep time of 10s. After thread 2 is created, it repeatedly generates random numbers until thread t1 terminates. Each time a random number is generated, it sleeps for 1s. If the generated random number is less than 0.2, it relaxes the interrupt request to t1. After thread t1 exits sleep, it first outputs the actual sleep time and then terminates

Here, we may prefer to create only one class, but multithreading in a class may lead to confusion, so we use inheritance to create two threads, so as to realize that the execution contents of the two threads are different. The previous topic is to create threads in threads, so it is a class

package ThreadDemo;

public class Thread1 extends Thread{
	@Override
	public void run() {
		System.out.println("enter t1");
		//Sleep for 10s, and record the time when you first sleep
		long primer_time = System.currentTimeMillis();
		try {
			Thread.sleep(10*1000);
		} catch (InterruptedException e) {
			System.out.println("t1 Interrupted");
		}
		//Final sleep time
		long end_time = System.currentTimeMillis();
		System.out.println("The actual time of sleep is :" + (end_time - primer_time)/1000+"s");
		System.out.println("t1 termination");
	}
}

Thread1 class only uses sleep and recording time, with the exception of being interrupted

package ThreadDemo;

public class Thread2 extends Thread{//To send a message to t1 at any time, include t1
	private Thread1 t1;
	
	public Thread2(Thread1 t1) {//Incoming t1
		this.t1 = t1;
	}
	@Override
	public void run() {
		System.out.println("enter t2");
		while(t1.isAlive())
		{
			double num = Math.random();
			System.out.println("t2 The random number generated is:"+ num);
			if(num < 0.2)
			{
				t1.interrupt();
			}
			try {//One number is generated at a time, sleeping for 1s
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("t2 termination");
	}
}

Here, since t2 needs to operate on t1, t1 should be passed into the construction method as an attribute of t2

Finally, start two threads with the starting class

package ThreadDemo;

public class ThreadDemo{
	public static void main(String[] args) {
		Thread1 t1 = new Thread1();
		Thread2 t2 = new Thread2(t1);
		t1.start();
		t2.start();
	}
}

One possible outcome is

enter t1
enter t2
The random number generated by t2 is 0.7462803496493212
The random number generated by t2 is 0.5418461826774316
The random number generated by t2 is 0.6781481265082193
The random number generated by t2 is 0.7426906269821782
The random number generated by t2 is 0.03640488973479594
t1 interrupted
Actual sleep time: 4s
t1 termination
t2 termination

Q3 simulated ticket buying

Topic content

Simulate three people buying tickets. Zhang, Li and Zhao buy tickets. The conductor has only three tickets of 5 yuan, and a movie ticket of 5 yuan. Zhang holds a 20 in front of Li, Li holds a 10 in front of Zhao, and Zhao holds a 5 yuan

Topic analysis

This topic allows you to simulate this process. There should be three threads corresponding to three people, which is a little similar to producers and consumers

Here, the conductor is a separate class. After the customer gives money, the operation is performed, and then a simulator is used to associate the conductor class. Different customers give different money

package ThreadDemo;

public class Seller {//Number of notes held
	private int num5 = 3; //3 sheets, 5 yuan
	private int num10 = 0;
	private int num20 = 0;
	
	//The ticket selling mode allows different operators to perform different operations before and after
	public synchronized void sell(int money)
	{//There are only three situations when customers submit money
		System.out.println(Thread.currentThread().getName());
		if(money == 5)//Five yuan is just right (the simplest)
		{
			num5 = num5 +1;
			System.out.println("The money is just right. Please take your ticket");
		}
		
		else if(money == 20){
			while(!((num10 >= 1&&num5 >= 1)||num5 >= 3))
			{
				System.out.println("20,No change, wait a minute");
				try {
					wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
				if(num10 >= 1)
				{
					num10 = num10 -1;
					num5 = num5 -1;
					num20 = num20 + 1;
					System.out.println("You give me 20 and find you a 10 and a 5");
				}
				else
				{
					num5 = num5-3;
					num20 = num20 +1;
					System.out.println("You give me 20 and find you three fives");
				}
		}
		
		else if(money == 10) {
			while(num5 < 1)
			{
				System.out.println("You give me 10,Your change is not enough. Please wait a minute");
				try {
					wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			num5 = num5 - 1;
			num10 = num10 + 1;
			System.out.println("You give me 10 yuan and I'll give you 5 yuan. Please take it");
		}
		notifyAll();//This wake-up can be done without adding specific pre objects
		System.out.println(Thread.currentThread().getName() +"end");
	}
}
//Here, I enlarged the scope of while and found the error by adding debugging statements

Then there is a simulator, which is very troublesome if you put the code directly into

package ThreadDemo;

public class Simulater implements Runnable{
	private Seller bc;
	private int money;
	
	public Simulater(Seller bc, int money) {
		this.bc = bc;
		this.money = money;
		new Thread(this).start();
	}

	@Override
	public void run() {
		bc.sell(money);
	}
}

Finally, use a starting class to simulate queuing

package ThreadDemo;

public class ThreadDemo{
	public static void main(String[] args) {
		Seller bc = new Seller();
		new Simulater(bc,20);
		new Simulater(bc,10);
		new Simulater(bc,5);
	}
}

One possible result after running is

Thread-0
You give me 20 and find you three fives
Thread-0 end
Thread-2
The money is just right. Please take your ticket
End of Thread-2
Thread-1
You give me 10 yuan and I'll give you 5 yuan. Please take it
End of Thread-1

Here is also a comprehensive application, about the application of locks

Basically, most of the knowledge of threads is used through these three topics. The application of the third one is very simple on the whole, but what we need to pay attention to is the idea when creating the class. Here, we can find the ticket window and three people from the topic, and there is a process of changing money. Therefore, we should make the ticket Seller a class Seller, and its attribute is the paper it owns Coin, the method is to sell tickets, and the simulation is to connect people and the ticket window. Each person is a thread, and put the ticket selling method into run.

File file

The reason why this class is mentioned separately here is that this part was omitted during IO, so now let's analyze this part in detail.

When it comes to program development, it must be inseparable from the operation of files, such as file IO and FileOutputStream. The innermost layer of the filter stream must be the media stream. For the file stream, you need to create a file object.

How does java access file properties?

Through Java API: java.io.File class

How do I get a file object?

Here, we use the construction method of the File class to obtain the File object through the path of the incoming File

File file = new File("D:\\java\\wb\\Hello.txt"); //The path here exists as a string

Note that the directory in the path is a double slash instead of a single slash, while the path in the disk is a single slash, which is caused by the escape character. If the single slash is used, the escape character must be used

Here, if a file exists, it is only accessed. If it does not exist, a file will be created. File provides a method createNewFile() to determine whether a new file has been created. There is also a method to delete the file, a method to specify whether the file exists, and a method to print the absolute path of the file getAbsolutePath(), lenth the file size (in bytes) , / 1024 is kb. There are many methods that can be queried directly in the java API

Since the content of the file is relatively simple, we won't continue to share it. Later, we will analyze the container classes in Java in detail to compare how to operate various data structures conveniently~

Posted by rachae1 on Mon, 11 Oct 2021 11:06:34 -0700