java simple use of multithreading

A program is a collection of instructions written in a language to accomplish a specific task. That is, a piece of static code, a static object.
A process is an execution of a program, or a program that is running. It is a dynamic process: a process of its own creation, existence and demise. ——Life cycle
   such as: running QQ, running MP3 player
          program is static, process is a dynamic process as the unit of resource allocation, the system will allocate different memory area threads (threads
) for each process at runtime.
), a process can be further refined into a thread, which is an execution path within a program.

  • If a process executes multiple threads in parallel at the same time, it supports multithreading
  • Thread as the unit of scheduling and execution, each thread has an independent running stack and program counter (pc), the overhead of thread switching is small
  • Multiple threads in a process share the same memory unit/memory address space  They allocate objects from the same heap and can access the same variables and objects.
  • This makes communication between threads easier and more efficient. However, the system resources shared by multiple threads may bring security risks.

Understanding of single-core CPU and multi-core CPU

A single-core CPU is actually a fake multi-threading , because in a time unit, only one thread's task can be executed. For example: Although there are multiple lanes, but only one staff member is charging at the toll station, and only after the toll can pass through, then the CPU is like the toll collector. If there is someone who doesn't want to pay, then the toll collector can "hang" him (leave him on hold, wait until he figured it out and has the money ready before going to charge). But because the CPU time unit is so short, it doesn't feel like it.
If it is multi-core, the efficiency of multi-threading can be better played. ( Current servers are all multi-core) A Java application java.exe actually has at least three threads: main() main thread, gc()
garbage collection thread, and exception handling thread. Of course, if an exception occurs, it will affect the main thread.


 Parallelism and Concurrency


Parallel: Multiple CPUs perform multiple tasks at the same time. For example: multiple people doing different things at the same time.
Concurrency: One CPU (using time slices) executes multiple tasks at the same time. For example: spike, multiple people doing the same thing

Thread creation and startup

The JVM of the Java language allows programs to run multiple threads, which are represented by the java.lang.Thread class.

Features of the Thread class

  1. Each thread completes the operation through the run() method of a specific Thread object, and the body of the run() method is often referred to as the thread body
  2. Start the thread through the start() method of the Thread object instead of calling run() directly

Thread class constructor

Thread() : Create a new Thread object
Thread(String threadname): : Create a thread and specify the thread instance name
Thread(Runnable target) : Specify the target object for creating a thread, which implements the run method
Thread(Runnable target, String name) : create a new Thread object

.thread creation

Three ways:

  1. Inherit from the Thread class
  2. Implement the Runnable interface
  3. Implement the Callable interface

Method 1: Inheriting the Thread class
1) Define a subclass to inherit the Thread class.
2) Override the run method in the Thread class in the subclass.
3) Create a Thread subclass object, that is, create a thread object.
4) Call the thread object start method: start the thread and call the run method.



//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程

//总结:注意,线程开启不一定立即执行,由cpu调度执行
public class TestThread1 extends Thread{

    @Override
    public void run() {
        super.run();
        //run方法线程体
        for(int i=0;i<20;i++){
            System.out.println("我在看代码----"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程

        //创建一个线程对象
        TestThread1 testThread1=new TestThread1();
        //调用start()方法开启线程
        testThread1.start();

        for (int i = 0; i < 2000; i++) {
            System.out.println("我在学习多线程---"+i);
        }
    }
}

Points to note:
1. If you manually call the run() method, it is just an ordinary method, and the multi-threading mode is not activated.
2. The run() method is called by the JVM. When it is called, the process control of the execution is
determined by the CPU scheduling of the operating system.
3. To start multithreading, you must call the start method.
4. A thread object can only call the start() method once to start. If it is called repeatedly, the above
exception "IllegalThreadStateException" will be thrown

 Method 2: Implement the Runnable interface

1 ) Define a subclass that implements the Runnable interface.
2) Override the run method in the Runnable interface in the subclass.
3) Create a thread object through the Thread class parameterized constructor.
4) Pass the subclass object of the Runnable interface as the actual parameter to the constructor of the Thread class.
5) Call the start method of the Thread class: start the thread and call the run method of the Runnable subclass interface.

//创建线程方式:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{


    public void run() {
        //run方法线程体
        for(int i=0;i<200;i++){
            System.out.println("我在看代码----"+i);
        }

    }

    public static void main(String[] args) {
      //创建runnable接口的实现类对象
        TestThread3 testThread3=new TestThread3();
        //创建线程对象,通过线程对象来开启我们的线程,代理
    //    Thread thread=new Thread(testThread3);
    //    thread.start();
        new Thread(testThread3).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("我在学习多线程---"+i);
        }



    }
}
*例子:买火车票 */
public class TestThread4 implements Runnable{
    //票数
    private int ticketNums = 10;

    @Override
    public void run() {
        while (true){
            if(ticketNums<=0) break;

            try { //模拟延时
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
        }
    }
    public static void main(String[] args) {
        TestThread4 ticket = new TestThread4();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"老师").start();
        new Thread(ticket,"黄牛党").start();
    }
    //问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
}
//龟兔赛跑
public class Race implements Runnable{
    //胜利者
    private static String winner;

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {

            boolean flag=gameOver(i);//判断比赛是否结束
            if(flag) break;

            System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");

            //模拟兔子休息
            if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //判断是否完成比赛
    private boolean gameOver(int steps){
        if(winner!=null){
            return true;
        }{
            if (steps==100){
                winner=Thread.currentThread().getName();
                System.out.println("winner is"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}

The connection and difference between inheritance and implementation

Differences
 in inheritance Thread: The thread code is stored in the run method of the Thread subclass.
Implement Runnable: The run method of the subclass of the interface where the thread code exists.
The benefits of implementation
 avoid the limitations of single inheritance
Multiple threads can share objects of the same interface implementation class, which is very suitable for multiple identical threads to process the same resource

Related methods of Thread class

  1. void start(): Start the thread and execute the object's run() method
  2. run(): what the thread performs when it is scheduled
  3. String getName(): Returns the name of the thread
  4. void setName(String name): Set the thread name
  5. static Thread currentThread(): Returns the current thread. It is this in the Thread subclass, which is usually used for the main thread and the Runnable implementation class
  6. static void yield(): : The thread yields to suspend the currently executing thread and gives the execution opportunity to a thread of the same or higher priority. If there is no thread of the same priority in the queue, ignore this method
  7. join() : : When a program execution flow calls the join() method of other threads, the calling thread will be blocked until the join thread joined by the join() method is executed, and the low-priority thread can also be executed
  8. static void sleep(long millis): (specified time: milliseconds) Make the current active thread give up control of the CPU within the specified time period, so that other threads have the opportunity to be executed, and requeue after the time is up.
  9. Throws InterruptedException
  10. stop(): Force the thread lifetime to end, not recommended
  11. boolean isAlive(): : Returns boolean to determine whether the thread is still alive

Method 3: Implement the Callable interface and need a return value type

Override the call method to throw an exception

Create target object

Create an execution service: ExecutorService ser = Executors.newFixedThreadPool(1);

Submit for execution: Future result1 = ser.submit(11);

Get the result: boolean r1 = result1.get()

Shut down the service: ser.shutdownNow();
 


import org.apache.commons.io.FileUtils;

import java.io.File;
import java.net.URL;
import java.util.concurrent.*;

//线程创建方式三:实现callable接口
public class TestCallable implements Callable<Boolean> {

    private String url;//网络图片地址
    private String name;//保存的文件名

    public TestCallable(String url, String name) {
        this.url = url;
        this.name = name;
    }

    public Boolean call() throws Exception {
        WebDownLoader2 webDownLoader=new WebDownLoader2();
        webDownLoader.downloader(url,name);
        System.out.println("下载了文件名为"+name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable testThread21=new  TestCallable("http://wanwan.group/images/index0.jpg","1.jpg");
        TestCallable testThread22=new  TestCallable("http://wanwan.group/images/index0.jpg","2.jpg");
        TestCallable testThread23=new  TestCallable("http://wanwan.group/images/index0.jpg","3.jpg");
        TestCallable testThread24=new  TestCallable("http://wanwan.group/images/index0.jpg","4.jpg");
        TestCallable testThread25=new  TestCallable("http://wanwan.group/images/index0.jpg","5.jpg");
        TestCallable testThread26=new  TestCallable("http://wanwan.group/images/index0.jpg","6.jpg");

        //创建执行服务
        ExecutorService service= Executors.newFixedThreadPool(3);

        //提交执行
        Future<Boolean> result=service.submit(testThread21);
        Future<Boolean> result2=service.submit(testThread22);
        Future<Boolean> result3=service.submit(testThread23);

        //获取结果
        boolean rs1=result.get();
        boolean rs2=result2.get();
        boolean rs3=result3.get();

        //关闭服务
        service.shutdownNow();

    }
}
//下载器
class WebDownLoader2{

    //下载方法
    public void downloader(String url,String name){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现问题");
        }


    }


}

Thread courtesy

  • Polite thread, allowing the currently executing thread to pause, but not block
  • Transition a thread from running state to ready state
  • Let the CPU reschedule, but politeness may not be successful, depending on the mood of the CPU

public class TestYield {
    public static void main(String[] args) {
        MyYield myYield = new MyYield(); //一个对象两个线程
        //礼让不一定成功
        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }
}

class MyYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");
        Thread.yield(); //礼让
        System.out.println(Thread.currentThread().getName()+"线程停止执行");
    }
}

thread jumping

  • Join merge threads. After the thread execution is completed, other threads are executed and other threads are blocked.
/*
测试join方法,线程插队,强制执行,阻塞其他线程,尽量少用
 */
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <= 1000; i++) {
            System.out.println("线程vip来了"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start(); //启动我们的线程

        //主线程
        for (int i = 0; i <= 500; i++) {
            if(i==200){
                thread.join();//插队,等线程执行完
            }
            System.out.println("main"+i);
        }
    }
}

thread priority


Thread's priority level MAX_PRIORITY
: 10
MIN _PRIORITY: 1
NORM_PRIORITY: 5

 Involved method
getPriority() : : Returns the thread priority value
setPriority(int newPriority) : : Changes the thread's priority
 Description:
When a thread is created, it inherits the priority of the parent thread.
Low priority is only a low probability of getting scheduling, not necessarily high
Called

// 优先级
public class TestPriority{
    
    public static void main(String[] args) {
        //main 默认优先级 5
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
        
        MyPriority myPriority = new MyPriority();

        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);
        Thread t5 = new Thread(myPriority);

        //先设置优先级,再启动
        t1.start();  //Thread-0 默认优先级 5

        t2.setPriority(1);
        t2.start();

        t3.setPriority(4);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY); //最大优先级
        t4.start();

        t5.setPriority(3);
        t5.start();
    }
}

class MyPriority implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    }
}

Daemon thread

  • Threads are divided into user threads and daemon threads
  • The virtual machine must ensure that the user thread has finished executing
  • The virtual machine does not have to wait for the daemon thread to finish executing
  • For example, record operation logs in the background, monitor memory, wait for garbage collection...

//测试守护线程 daemon
public class TestDaemon {

    public static void main(String[] args) {
        God god = new God();
        You you = new You();

        //上帝是守护线程,用户线程结束自己也结束
        Thread thread = new Thread(god); 
        thread.setDaemon(true); //设置为守护线程 默认是false(表示用户线程)
        
        thread.start(); //守护线程启动

        new Thread(you).start(); //用户线程启动
    }

}

class God implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("上帝保佑着你");
        }
    }
}

class You implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("你度过了开心的第"+i+"天");
        }
        System.out.println("-==goodbye,world!==-");
    }
}

Guess you like

Origin blog.csdn.net/qq_44716544/article/details/119143464