JAVA learning - process, multithreading, Thread class and Runnable interface, multithreaded program security, synchronized, lock, wait and wake up

process

Running program, an independent unit for resource allocation and invocation by the system

Thread: A single sequential flow of control in a process, which is one
path of execution Single-threaded, Multi-threaded: A process has single or multiple execution paths

Implementation of multithreading 1-inheriting the Thread class

The first implementation of multithreading

Set and get thread name

getName
setName

thread scheduling

1. Time-sharing scheduling model
2. Preemptive scheduling model: Prioritize high-priority threads to use the CPU; (the method used by JAVA)
return priority:
public final int getPriority​(): returns the priority of this thread.
public final void setPriority​(int newPriority)
Changes the priority of this thread. (The default is 5, the range is between 1-10)
Code example:
declare a class that implements the Thread interface

//继承Thread方法
public class duoxiancheng extends Thread {
    
    
    @Override //重写run方法
    public void run() {
    
    
        for(int i = 0; i<100; i++){
    
    
            System.out.println(getName()+":"+i);
        }

Run class:

        duoxiancheng d1 = new duoxiancheng();
        duoxiancheng d2 = new duoxiancheng();
        duoxiancheng d3 = new duoxiancheng();
        d1.setName("shouhu1");
        d2.setName("shouhu2");
        d3.setName("laiha");
        d1.start();
        d2.start();
        d3.start();

thread control

thread control method
setDeamon: Set the thread as a daemon thread (non-main thread, secondary thread). If the main thread ends, when the running threads are all daemon threads, the JAVA virtual machine exits

thread life cycle

thread life cycle

Implement multithreading method 2- the way to implement the Runnable interface

runnable
The Runnable interface is implemented by any class whose instances will be executed by threads.
Implements the Runnable class Thread by instantiating a Thread instance and running itself as the target, without subclassing Thread.
In most cases, you should use the Runnable interface if you only plan to override the run() method and not use other Thread methods.
Thread​(Runnable target, String name) allocates a new Thread object.
After creating the Thread class object, use the thread object as the parameter of the construction method
Code example:
implement the runnabl interface:

public class runable implements Runnable{
    
    

    @Override
    public void run() {
    
    
        for(int i=0;i<100;i++)
        System.out.println(Thread.currentThread().getName()+":"+i);
    }

Main program:

        runable ra = new runable();

        Thread tr1 = new Thread(ra,"meimei");
        Thread tr2 = new Thread(ra,"keke");
        
        tr1.start();
        tr2.start();

Benefits of Runnable over Thread

1. Avoid the limitations of JAVA single inheritance.
2. It is suitable for multiple codes of the same program to process the same resource. It effectively separates threads from program codes and data, which better reflects the object-oriented thinking.

Safety of Multithreaded Programs

Security guarantee: lock the code that operates shared data with multiple statements, so that only one thread can execute at any time; JAVA provides a method of synchronizing code blocks to solve the problem

Synchronized code block

Benefits: Using synchronized to lock a statement block can solve multi-threaded data security issues;
Disadvantages: When there are many threads, since each thread will judge the synchronization lock, it will consume a lot of resources;

private int tickets = 1000;
//设定同一把锁
    private Object obj = new Object();

    @Override
    public void run() {
    
    
        while (true) {
    
    
        //锁线程
            synchronized (obj) {
    
    
                if(tickets>0) {
    
    
                         try {
    
    
                         //休息100MS便于其他线程抢到CPU
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets +"张票");
                        tickets --;
                }
            }
        }
    }

Test class:

        runable ra = new runable();

        Thread tr1 = new Thread(ra,"窗口一");
        Thread tr2 = new Thread(ra,"窗口二");
        Thread tr3 = new Thread(ra,"窗口三");

        tr1.start();
        tr2.start();
        tr3.start();

synchronization method

Synchronize ordinary methods:
modifier synchronized return value type method name (method parameter);
add the synchronized keyword to the method; the lock object of the synchronized method is: this;
synchronize static method:
modifier static synchronized return value type method name (method parameter);
the lock object of the synchronous static method is: class name.class

thread-safe classes

StringBuffer:

Thread-safe, mutable character sequences.
This class has been supplemented by an equivalent class designed to work with a thread, StringBuilder . Usually the StringBuilder class should be used since it supports all the same operations, but it is faster because it does not perform synchronization.

Vector:

Beginning with Java 2 platform v1.2, this class improves upon the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementation, Vector is synchronized. If you don't need a thread-safe implementation, it is recommended to use ArrayList instead of Vector

HashTable:

This class implements a hashtable that maps keys to values. Any non-null object can be used as key or value.
Starting with Java 2 platform v1.2, this class has been improved to implement the Map interface, making it a member of the Java Collections Framework. Unlike the new collection implementation, Hashtable is synchronized. If thread-safe implementation is not required, it is recommended to use HashMap instead of Hashtable

Lock lock

lock​() acquires the lock.
unlock​() releases the lock.
Lock is an interface that cannot be instantiated directly. It uses the implementation class ReentrackLock to instantiate.
Code example:
thread class:

public class runable implements Runnable{
    
    
    private int tickets = 100;
    private Lock lock = new ReentrantLock();//实例化

    @Override
    public void run() {
    
    
        while (true) {
    
    
            try {
    
    //用try finally的语法,try中有代码问题不影响锁操作
                lock.lock();//加锁
                {
    
    
                    if (tickets > 0) {
    
    
                    try {
    
    
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            }finally {
    
    
                lock.unlock();//释放锁
            }
        }
    }
}

Test class:

        runable ra = new runable();

        Thread tr1 = new Thread(ra,"窗口一");
        Thread tr2 = new Thread(ra,"窗口二");
        Thread tr3 = new Thread(ra,"窗口三");

        tr1.start();
        tr2.start();
        tr3.start();

Producer and Consumer Model

It needs to be used in synchronization;
waiting to wake up
after the wait and wakeup method wait, if other threads need to continue to operate, notify or notifyAll wakeup operation is required

Guess you like

Origin blog.csdn.net/weixin_52723971/article/details/111296897