• [Java] 多线程


    例1:单线程

    Punishment.java

    public class Punishment {
        private int leftCopyCount;
        private String wordToCopy;
    
        public Punishment(int i, String s) {
            this.leftCopyCount = i;
            this.wordToCopy = s;
        }
    
        public int getLeftCopyCount() {
            return leftCopyCount;
        }
    
        public void setLeftCopyCount(int leftCopyCount) {
            this.leftCopyCount = leftCopyCount;
        }
    
        public String getWordToCopy() {
            return wordToCopy;
        }
    
        public void setWordToCopy(String wordToCopy) {
            this.wordToCopy = wordToCopy;
        }
    }

    Student.java

    public class Student {
        private String name;
        private Punishment punishment;
    
        public Student(String name,Punishment punishment){
            this.name = name;
            this.punishment = punishment;
        }
    
        public void copyWord(){
            int count = 0;
            String threadName = Thread.currentThread().getName();
    
            while(true){
                if(punishment.getLeftCopyCount() > 0){
                    int leftCopyCount = punishment.getLeftCopyCount();
                    System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
                            --leftCopyCount + "次");
                    punishment.setLeftCopyCount(leftCopyCount);
                    count++;
                }else{
                    break;
                }
            }
            System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
        }
    } 

    StudentClient.java

    public class StudentClient {
        public static void main(String[] args) {
            Punishment punishment = new Punishment(100,"internationalization");
            Student student = new Student("小明",punishment);
            student.copyWord();
        }
    }
    

    main线程-小明抄写internationalization。还要抄写99次

    ...
    main线程-小明抄写internationalization。还要抄写0次
    main线程-小明一共抄写了100次!

    例2:继承Thread实现独立线程

    与例1不同处:

    • 继承Thread类
    • 调用Thread构造方法,设置threadName
    • 重写run方法,调用copyWord完成任务
    • 在main()中调用 start 方法

    Student.java

    public class Student extends Thread{
        private String name;
        private Punishment punishment;
    
        public Student(String name,Punishment punishment){
            super(name);
            this.name = name;
            this.punishment = punishment;
        }
    
        public void copyWord(){
            int count = 0;
            String threadName = Thread.currentThread().getName();
    
            while(true){
                if(punishment.getLeftCopyCount() > 0){
                    int leftCopyCount = punishment.getLeftCopyCount();
                    System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
                            --leftCopyCount + "次");
                    punishment.setLeftCopyCount(leftCopyCount);
                    count++;
                }else{
                    break;
                }
            }
            System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
        }
        @Override
        public void run(){
            copyWord();
        }
    }

    StudentClient.java

    public class StudentClient {
        public static void main(String[] args) {
            Punishment punishment = new Punishment(100,"internationalization");
            Student student = new Student("小明",punishment);
            student.start();
            System.out.println("Another thread will finish the punishment。 main thread is finished" );
        }
    }
    

    Another thread will finish the punishment。 main thread is finished
    小明线程-小明抄写internationalization。还要抄写99次

    ...

    小明线程-小明抄写internationalization。还要抄写0次
    小明线程-小明一共抄写了100次!

    例2:继承Thread实现多线程

    StudentClient.java

    public class StudentClient {
        public static void main(String[] args) {
            Punishment punishment = new Punishment(100,"internationalization");
            Student xiaoming = new Student("小明",punishment);
            xiaoming.start();
            Student xiaozhang = new Student("小张",punishment);
            xiaozhang.start();
            Student xiaozhao = new Student("小赵",punishment);
            xiaozhao.start();
        }
    }
    

    小明线程-小明一共抄写了100次!

    小张线程-小张一共抄写了100次!

    小赵线程-小赵一共抄写了100次!

    例3:继承Runnable实现多线程

    Student.java

    public class Student implements Runnable{
        private String name;
        private Punishment punishment;
    
        public Student(String name,Punishment punishment){
            this.name = name;
            this.punishment = punishment;
        }
    
        public void copyWord(){
            int count = 0;
            String threadName = Thread.currentThread().getName();
    
            while(true){
                if(punishment.getLeftCopyCount() > 0){
                    int leftCopyCount = punishment.getLeftCopyCount();
                    System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
                            --leftCopyCount + "次");
    //              --leftCopyCount;
                    punishment.setLeftCopyCount(leftCopyCount);
                    count++;
                }else{
                    break;
                }
            }
            System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
        }
        @Override
        public void run(){
            copyWord();
        }
    }  

    StudentClient.java

    public class StudentClient {
        public static void main(String[] args) {
            Punishment punishment = new Punishment(100,"internationalization");
            Thread xiaoming = new Thread(new Student("小明",punishment));
            xiaoming.start();
        }
    }

    结果同例2

    例4:多线程同时抄写

    • 取得剩余次数后马上更新-1后的次数。看似是避免了读取和更新间的时间间隔
    • 更新剩余次数前先判断自己的更新次数是否为最新,避免更新后次数反而变大的问题
    • 有小概率两人甚至三人同时查看剩余次数,导致重复抄写

    Student.java

    public class Student extends Thread{
        private String name;
        private Punishment punishment;
    
        public Student(String name,Punishment punishment){
            super(name);
            this.name = name;
            this.punishment = punishment;
        }
    
        public void copyWord(){
            int count = 0;
            String threadName = Thread.currentThread().getName();
    
            while(true){
                if(punishment.getLeftCopyCount() > 0){
                    int leftCopyCount = punishment.getLeftCopyCount();
                    leftCopyCount--;
                    if(leftCopyCount<punishment.getLeftCopyCount()){
                        punishment.setLeftCopyCount(leftCopyCount);
                    }
                    System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
                            leftCopyCount + "次");
                    count++;
                }else{
                    break;
                }
            }
            System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
        }
        @Override
        public void run(){
            copyWord();
        }
    } 

    StudentClient.java

    public class StudentClient {
        public static void main(String[] args) {
            Punishment punishment = new Punishment(100,"internationalization");
            Student xiaoming = new Student("小明",punishment);
            xiaoming.start();
            Student xiaozhang = new Student("小张",punishment);
            xiaozhang.start();
            Student xiaozhao = new Student("小赵",punishment);
            xiaozhao.start();
        }
    }
    

    小赵线程-小赵一共抄写了34次!
    小张线程-小张一共抄写了22次!
    小明线程-小明一共抄写了44次!

    例5:解决线程安全问题

    参考

    java多线程是并发还是并行

    https://blog.csdn.net/gxl1989225/article/details/84912017

  • 相关阅读:
    024_Python3 filter 函数高级用法
    023_Python3 map 函数高级用法
    022_Python3 lambda函数高级用法
    #整体二分,树状数组#洛谷 3332 [ZJOI2013]K大数查询
    #线段树分治,线性基,并查集#CF938G Shortest Path Queries
    #RMQ,动态开点线段树#CF803G Periodic RMQ Problem
    #二分图匹配#UVA1194 Machine Schedule
    #树状数组套线段树#洛谷 1975 [国家集训队]排队
    #分治,Dijkstra#洛谷 3350 [ZJOI2016]旅行者
    #线段树,离线#CF1000F One Occurrence
  • 原文地址:https://www.cnblogs.com/cxc1357/p/13771427.html
Copyright © 2020-2023  润新知