Java learning 4-7_callback function

Callback

1. Definition

A callback function is a function called through a function pointer . If the pointer (address) of a function is passed as a parameter to another function, when this pointer is used to call the function it points to, we say that this is a callback function. The callback function is not called directly by the implementer of the function, but is called by another party when a specific event or condition occurs, and is used to respond to the event or condition.

Insert picture description here

2. Steps:

  1. Type Aof a()method calls the class B's b()methods
  2. BThe b()method of the class is executed and Athe callbackmethod of the class is actively called

There is no function pointer in Java, and it is usually implemented through an interface: assign a reference to an object created by a class that implements an interface to the interface variable declared by the interface, then the interface variable can call the method of the interface implemented by the class.

3. Example (using the interface to implement callbacks, and passing objects is also possible)

Probably it is a network programming code that simulates the pickup operation of the express cabinet. When the socketcommunication problem was not solved during the transformation , the code was deleted and then posted.

1. Callback interface
/**
 * 回调接口
 * @author ShiYu
 *
 */
public interface CallBackInterface {
    
    
	void call();
}
2. To use callbacks, use a class to implement the callback interface, rewrite the call()method, that is, the function that implements the callback at the end (Class B in the figure above)
/**
 * 实现接口,在这个类的方法中去调用另一个类的方法
 * Make a complaints by ShiYu:本来用Runnable接口也挺香的,非要整点炫酷的给自己挖坑 0_o?
 * @author ShiYu
 */
public class ClientThreadCallBack implements CallBackInterface {
    
    
    //此处相当于
	ExpressServerCallback expressServerCallback = new ExpressServerCallback();
	private Socket socket;

	// 构造函数将合传入
	public ClientThreadCallBack(Socket socket) {
    
    
		this.socket = socket;
	}

	@Override
	public void call() {
    
    
		// TODO Auto-generated method stub
		System.out.println("回调");

		new Thread(() -> {
    
    
			// 线程信息
			System.out.println("cilent<" + Thread.currentThread().getName() + ">");
			System.out.println("\"" + socket.toString() + "\"");
			System.out.println("socket Info client port:" + socket.getPort());
			try {
    
    
				while (true) {
    
    
					System.out.println("输入的取件码:");
					String keyPackageNumber = br.readLine();// 阻塞方法
					System.out.println(keyPackageNumber);

                      //调用另一个类的方法,socket是引用类型
					ExpressServerCallback.takeOut(socket, keyPackageNumber);
				}
			} catch (Exception e) {
    
    
				e.printStackTrace();
			}
		}).start();
	}
}
3. mainOpen the call in the method of this class ( )
/**
 * main方法,使用回调函数
 * @author ShiYu
 */
public class ExpressServerCallback {
    
    
	static ArrayList<Express> expressCabinet  = new ArrayList<>();
	public static void main(String[] args) {
    
    
		//从工具类获取server实例,单例模式(懒汉)
		ServerSocket serverSocket = SocketUtils.getInctence();
		try(serverSocket) {
    
    
			while (true) {
    
    
				Socket socket = serverSocket.accept();//阻塞方法
				//调用
				ClientThreadCallBack cliBack = new ClientThreadCallBack(socket);
				cliBack.call();
			}
		} catch (IOException e) {
    
    
			e.printStackTrace();
		}
	}

	public synchronized static boolean takeOut(Socket socket, String keyPackageNumber) {
    
    
		//省略
	}
	
	/**
	 * 发送信息
	 * @param msg
	 * @return
	 */
	public static boolean sendMassage(Socket socket, String msg) {
    
    
		//省略
	}
}
4. Description

The original intention of this example is to mainuse the callback method in the method to open the communication thread for multiple users, and then if the client tube sends data, mainthe addition, deletion, and modification of the member variable collection in the class where the callback method is located, the process:

1.ExpressServerCallback.main -> cliBack.call()

ExpressServerCallbackClass mainmethod, the instance of ClientThreadCallBackthe object class, calling ClientThreadCallBack.call()methods

2.ClientThreadCallBack.call() -> ExpressServerCallback.takeOut()

​ In ClientThreadCallBackthe call method in the class, after a blocking method (or other judgment conditions), when the conditions are met, go back and call the ExpressServerCallbackmethod in the collection operation

Four. Postscript

The original intention is to avoid passing the collection to the same collection when multi-threaded operation, and then think of this seemingly fun method, and as a result, a bug appeared in the socket. It has not been resolved until now. socketUncontrolled sending There was an empty data, which caused a problem with the process connection between the client and the server

Actually I mentioned this Vector

public synchronized E remove(int index) {
    
    
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; // Let gc do its work

        return oldValue;
    }

You can see that the synchronized built-in lock is used in the source code. Of course, multithreading must sacrifice efficiency if it wants to ensure thread safety.

Guess you like

Origin blog.csdn.net/Sky_Coolssy/article/details/108904684