JAVA programmer's notes Chapter 19 - reflection, dynamic proxy, multithreading

Reflection (Reflex)

Java reflection mechanism can make Java Dynamic. In the running state, all properties and methods of a class can be obtained;
For any object, you can call any of its methods and properties; This function of dynamically obtaining information and calling object methods is called java reflection mechanism.
When using reflection, we must recognize that Class objects (Class classes) are objects of Class type corresponding to each bytecode file

Class class

In Java, classes are the smallest unit. The Class class represents the Class or interface in the running Java program. When the JVM reads a Class, Class loading will occur (see previous notes for Class loading knowledge) and generate Class objects.
So, can I create class objects by constructing methods?
of course.... No, class has no public constructor (it is privatized). Class objects can only be automatically constructed by the virtual machine JVM and the defineClass method in the class loader when the class is loaded.

Use of reflection

 // There are three ways to obtain class objects
        // 1. Class.class
        	//Gets the class object of the User
       		 Class<User> clz = User.class;
        // 2. Object. getClass()
        		clz.g.getClass()
        // 3. Class. Forname ("class full name"): package name + class name
				Class<?> clz3 = Class.forName("java.lang.String") ;

Common API

 //Gets the class object of the User
        Class<User> clz = User.class;

        //Quickly create objects through the parameterless construction method
        User user = clz.newInstance();
        System.out.println(user);

        Object o = clz.getDeclaredConstructor().newInstance();

        //Gets all constructors of the User class
        Constructor<?>[] constructors = clz.getConstructors();

        Constructor<?> constructor = constructors[1];

        //Parameter count
        int parameterCount = constructor.getParameterCount();
        System.out.println(parameterCount);

        //Parameter type
        Class<?>[] parameterTypes = constructor.getParameterTypes();

        for(Class<?> clzz : parameterTypes){
            System.out.println(clzz.getName());
        }

You can run the profile content through reflection

public class User{
	public void show(){
		System.out.println("is show()");
	}
}

configuration file

className = Day31_Reflex..User
methodName = show

Cross generic checking by reflection

public class Test03{
	public static void main(String[] args) throws Exception{
		ArrayList<String> list = new ArrayList<String>();
		list.add("HOU");
		list.add("hou");

		//Get the class object of ArrayList, get the add() method through reflection, and add data
		Class listClass = list.getClass(); 
		//Get add method
		Method method = listClass.getMethod("add", Object.class);
		
		method .invoke(list , 100);
		
		//Traversal set
		for(Object obj : strList){
			System.out.println(obj);
		}
	}
}

Dynamic agent

Through the reflection of Java, create an implementation class (dynamic proxy class) and object that implement some given interfaces when the program runs
The specific implementation of the agent interface is only known at run time.

Interface

public interface OrderDao {
    public List<Map<String, Object>> findOrdersByUser(String userName);

}

Implementation class

public class OrderDaoImpl implements OrderDao{
    @Override
    public List<Map<String, Object>> findOrdersByUser(String userName) {

        System.out.println("query" + userName + "All orders placed by users!!!");
        return null;
    }
}

proxy class

public class OrderDaoProxy implements OrderDao {

    private OrderDao orderDao ;

    public OrderDaoProxy(OrderDao orderDao) {
        this.orderDao = orderDao ;
    }

    @Override
    public List<Map<String, Object>> findOrdersByUser(String userName) {
        // Get the current system time, get the method name, and get the parameters
        StringBuilder sb = new StringBuilder();

        sb.append("execution time" + LocalDateTime.now())
                .append(", Method of execution findOrdersByUser ")
                .append(", The parameter passed in is userName=" + userName);

        List<Map<String, Object>> list = orderDao.findOrdersByUser(userName);

        sb.append("Return results" + list);

        System.out.println(sb);

        return list ;

    }
    }

Test class

public class TestStaticProxy {
    @Test
    public void test() {
        OrderDao orderDao = new  OrderDaoImpl() ;

        // Get proxy object
        orderDao  = new OrderDaoProxy(orderDao);

        // Let the proxy work instead of the target object
        orderDao.findOrdersByUser("admin");

    }
}

invoke has three parameters:

Proxy: it is the proxy object and the return object of newProxyInstance method
Method: called method
args: parameters of method

Multithreading

concept

Program: a set of instructions that can be recognized and executed.
Process: a running program that has a specified area in memory and is executed and calculated by the CPU.
Thread: the smallest unit that the operating system can perform operation scheduling. A process can start multiple threads. There is a main process to call other threads in the process.
There can be multiple processes in an operating system, and one process can contain one or more threads.

Serial and parallel

In a computer, a CPU can execute only one thread in a process. A CPU can only be serial
Parallel means that multiple CPU s can handle multiple things at the same time, which is called parallel, similar to two cars running side by side

CPU time-sharing scheduling

A CPU can execute only one thread in a process. When a thread is running, the CPU will randomly allocate a time slice to a thread (that is, how long you can work). When the time slice runs out, if the thread has not completed its work, the CPU will be deprived and allocated to another thread. Suspend the current thread. If the thread blocks or ends before the time slice runs out, the CPU will immediately switch to avoid waste of CPU resources. When switching to the previously suspended thread again, restore the site and continue execution.

1. New status: process object creation

2. Runnable state: when the start() method of the thread object is called, the thread is in the ready state. The thread in the runnable state only indicates that the thread is ready to wait for CPU scheduling and execution when > is selected, rather than calling the start() method, the thread will execute immediately

3. Running state: when the CPU schedules a thread in the ready state, the thread is the real execution, that is, it enters the running state. The ready state is the only entry to enter the running state >, that is, if the thread wants to enter the running state for execution, it must be in the ready state first

4. Blocking status: threads in the running status temporarily give up the right to use the CPU, stop execution and enter the blocking status for some reason. They will not have the opportunity to be selected by the CPU for execution again until they enter the ready status >

5. Dead status: when the thread has finished executing or exited the run() method due to an exception, the thread ends its life cycle.

Multi Thread creation method 1: inherit Thread
Thread class is essentially an instance that implements the Runnable interface and represents an instance of a thread. The only way to start a thread is through the start() instance method of thread class

Multithreading creation mode 2: implement Runnable interface
If a class already extends another class, it cannot inherit more than one class. You can implement a Runnable interface
When void run() creates a thread using the object that implements the interface Runnable, it will cause the run() method to call the object in the thread that is executed independently.

Case: selling tickets
Ticket category

public class Ticket {
    /**
     * Number of votes remaining
     */
    private int num ;

    /**
     * How many tickets are there
     * @param num
     */
    public Ticket(int num) {
        this.num = num ;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}

Ticket sales

public class TicketSystem {
    /**
     *  main The thread on which the method is located is called the master thread
     * @param args
     */
    public static void main(String[] args) throws Exception{

        // Create 100 tickets
        Ticket ticket = new Ticket(100);

        TicketWindow window = new TicketWindow(ticket);
        TicketWindow window2 = new TicketWindow(ticket);

        window.setname("Window 1");
        window2.setname("Window 2");


        //Single thread:

        // Open a ticket window to sell tickets
//        TicketWindow window = new TicketWindow(ticket);
        //Start thread
//        window.start();



        //Unsafe multithreading:
//        for (int i = 0; i < 3; i++) {
//            TicketWindow window = new TicketWindow(ticket);
//            System.out.println(window.getState());
//            window.start();
//
//        }

        //Multithreading
        window.start();
        window2.start();


//        Plus blocking
//        for (int i = 0; i < 3; i++) {
//            TicketWindow window3 = new TicketWindow(ticket);
//
//            //Thread state
//            System.out.println(window3.getState());
//
//            //Start thread
//            window3.start();
//
//            //Join the main thread and block the main thread
//            window3.join();
//
//            //If this line of code is executed, it indicates that the window thread has completed execution
//            System. Out. Println (Windows3. Getname() + "ticket selling completed");
//
//        }
    }
}

Ticket window class

public class TicketWindow extends Thread{

    public String name;
    //Store ticket
    public Ticket ticket;

    public String getname() {
        return name;
    }

    public void setname(String name){
         this.name = name;
    }

    public TicketWindow(Ticket ticket){
        this.ticket = ticket;
    }

    //Override run method
    @Override
    public void run(){
        try {
            this.sellTickets();//Ticket selling method
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *  Responsible for selling tickets
     */

    public void sellTickets()throws Exception {

        while (true) {
            synchronized (ticket) {
                //Remaining votes
                int num = ticket.getNum();
                if (num <= 0) {
                    System.out.println(this.getname() + "Window No. is sold out");
                    break;
                }

                System.out.println( this.getname()
                        + "Sold ticket No" + num + "Your ticket, Remaining" + (num - 1) + "Zhang");
                // The number of tickets is reduced by 1
                ticket.setNum(num - 1);

            }
            //Sleep time
            TimeUnit.MILLISECONDS.sleep(100);

            //sleep outside synchronized, wait inside synchronized
            /**
             * sleep() :
             * It will sleep for the specified time and give up the execution permission of CPUC, but it will not release the synchronization lock
             *
             * wait(timeout):
             *     When the waiting time is passed in, it will wait for the specified time period. Giving up the CPU execution permission will release the lock
             *
             *
             *      wait It is the method of Object class. Only the Object with lock (critical resource sharing Object) can call wait
             *
             */

        }
    }
}

Tags: Java

Posted on Mon, 06 Sep 2021 16:02:11 -0400 by harchew