• 线程的互斥和协作


    public class Synchronized{
        static class Account{
            private double money = 1000.0d;
            
            //异步存钱
            public void noSynDesposit(double fFees){
                System.out.println("Account noSynDesposit begin! money = "+ this.money + "; fFees = "+fFees);
                System.out.println("noSynDesposit sleep begin");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                System.out.println("noSynDesposit end");
                this.money = this.money + fFees;
                System.out.println("Account noSynDesposit end! money = "+ this.money);
                }
                
            //异步取钱
            public void noSynWithdraw(double fFees){
                System.out.println("Account noSynWithdraw begin! money = "+ this.money + "; fFees = "+fFees);
                System.out.println("noSynWithdraw sleep begin");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                System.out.println("noSynWithdraw sleep end");
                this.money = this.money - fFees;
                System.out.println("Account noSynWithdraw end! money = "+ this.money);
                }
                
            //同步存钱
            public synchronized void synDesposit(double fFees){
                System.out.println("Account synDesposit begin! money = "+ this.money + "; fFees = "+fFees);
                System.out.println("synDesposit sleep begin");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                System.out.println("synDesposit end");
                this.money = this.money + fFees;
                System.out.println("Account synDesposit end! money = "+ this.money);
                }    
                
            //同步取钱
            public synchronized void synWithdraw(double fFees){
                System.out.println("Account synWithdraw begin! money = "+ this.money + "; fFees = "+fFees);
                System.out.println("synWithdraw sleep begin");
                try{
                    Thread.sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
                System.out.println("synWithdraw sleep end");
                this.money = this.money - fFees;
                System.out.println("Account synWithdraw end! money = "+ this.money);
                }
            }
            
        static class AccessThread extends Thread{
            private Account account = null;
            private String method = "";
            public AccessThread(Account account, String method){
                this.account = account;
                this.method = method;
                }
                
            public void run(){
                if(method.equals("noSynDesposit")){
                    account.noSynDesposit(500.0);
                }else if(method.equals("noSynWithdraw")){
                    account.noSynWithdraw(200.0);
                }else if(method.equals("synDesposit")){
                    account.synDesposit(500.0);
                }else if(method.equals("synWithdraw")){
                    account.synWithdraw(200.0);
                    }
            }
        }
            
        public static void main(String[] args){
            //线程的运行具有不确定性,与启动顺序无关,取决于JVM,所以异步就可能出现
            Account account = new Account();
            //同一个账户多个线程调用不同的方法,修改同一个变量值
            System.out.println("account 1 :"+account.toString());
            Thread threadA = new AccessThread(account, "noSynDesposit");
            Thread threadB = new AccessThread(account, "noSynWithdraw");
            threadA.start();
            threadB.start();
            
            try{
                //waits for this thread to die
                threadA.join();
                threadB.join();
            }catch(InterruptedException e){
                e.printStackTrace();
                }
            
            System.out.println();
            account = new Account();
            System.out.println("account 2 :"+account.toString());
            Thread threadC= new AccessThread(account, "synDesposit");
            Thread threadD = new AccessThread(account, "synWithdraw");
            threadC.start();
            threadD.start();
            }
        }
    G:maul keyboard	hread>java Synchronized
    account 1 :Synchronized$Account@153bcbc8
    Account noSynDesposit begin! money = 1000.0; fFees = 500.0
    Account noSynWithdraw begin! money = 1000.0; fFees = 200.0
    noSynWithdraw sleep begin
    noSynDesposit sleep begin
    noSynWithdraw sleep end
    Account noSynWithdraw end! money = 800.0
    noSynDesposit end
    Account noSynDesposit end! money = 1300.0
    
    account 2 :Synchronized$Account@1b61d282
    Account synDesposit begin! money = 1000.0; fFees = 500.0
    synDesposit sleep begin
    synDesposit end
    Account synDesposit end! money = 1500.0
    Account synWithdraw begin! money = 1500.0; fFees = 200.0
    synWithdraw sleep begin
    synWithdraw sleep end
    Account synWithdraw end! money = 1300.0
    
    G:maul keyboard	hread>
    import java.util.Vector;
    
    
    public class WaitNotify{
        static class Printer extends Thread{
            /**
            1.start、run、addTask、stopPrinter因为要协同作用,所以都没有使用synchronized同步,所以他们的运行没有先后顺序
            2.通过其他方法(addTask、stopPrinter)来修改线程占用对象的资源,并控制线程的运行(run方法)
            3.addTask、stopPrinter方法中的synchronized代码块,同一时刻仅允许一个线程进入,控制同一变量因不同方法修改而不一致
            4.线程处于等待状态仅仅是线程暂停运行run方法了,线程还可以运行属于它的其他方法,通过其他方法唤醒线程,继续运行run方法
            5.在线程协同场景下,线程一般结合synchronized代码块使用
            */
            Vector task = new Vector();
            private boolean running = false;
            public void start(){
                running = true;
                super.start();
                }
            public void run(){
                try{
                    System.out.println("printer begin");
                    while(running){
                        System.out.println("task.isEmpty :"+task.isEmpty()+" running : "+running);
                        //同步代码块,同一时间只允许一个线程访问该对象,避免task属性不一致
                        synchronized (this){
                            while(task.isEmpty() && running){
                                System.out.println("wait begin");
                                //线程等待,释放所占对象所有资源
                                this.wait();
                                System.out.println("wait end");
                                }
                            }
                    if(running){
                        //不断打印队列首个消息,打印时一并移出
                        System.out.println("print the task : "+task.remove(0));
                        }
                    }
                    System.out.println("printer end");
                }catch(InterruptedException e){
                    e.printStackTrace();
                    }
            
                }
            //使用线程释放的资源,修改资源后,再唤醒线程继续执行
            @SuppressWarnings("unchecked")    
            public void addTask(String str){
                synchronized (this){
                    this.task.add(str);
                    System.out.println("task size : "+task.size());
                    this.notify();
    //                this.notifyAll();
                    }
                }
                
            public void stopPrinter(){
                synchronized (this){
                    this.running = false;
                    System.out.println("stopPrinter notify");
                    this.notify();
                    }
                }
            }
        
        public static void main(String[] args){
            //线程和线程操作的对象是同一个
            Printer printer = new Printer();
            printer.start();
            System.out.println("==========================================================");
            try{
                //留出休眠时间等待线程把符合条件的语句执行完
                Thread.sleep(200);
                for(int i=0;i<3;i++){
                    //1.留出休眠时间等待线程被唤醒,再生成任务
                    //2.留出休眠时间等待任务生成
                    Thread.sleep(200);
                    printer.addTask("The task "+i);
                }
            }catch(InterruptedException e){
                e.printStackTrace();
                }
                
            try{
                //留出休眠时间等待线程执行完,如果不休眠等待,则可能所有的任务不能都执行完
                Thread.sleep(200);
                printer.stopPrinter();
            }catch(InterruptedException e){
                e.printStackTrace();
                }
            }
        }
    G:maul keyboard	hread>java WaitNotify
    ==========================================================
    printer begin
    task.isEmpty :true running : true
    wait begin
    task size : 1
    wait end
    print the task : The task 0
    task.isEmpty :true running : true
    wait begin
    task size : 1
    wait end
    print the task : The task 1
    task.isEmpty :true running : true
    wait begin
    task size : 1
    wait end
    print the task : The task 2
    task.isEmpty :true running : true
    wait begin
    stopPrinter notify
    wait end
    printer end
    
    G:maul keyboard	hread>
  • 相关阅读:
    .Net Core 5.x Api开发笔记 -- 消息队列RabbitMQ实现事件总线EventBus(二)
    .Net Core 5.x Api开发笔记 -- 消息队列RabbitMQ实现事件总线EventBus(一)
    SQL 入门教程:创建视图
    微信小程序-企业微信PC端,对接echarts图无法显示
    SQL查看表结构以及表说明
    Skoruba.IdentityServer4.STS.Identity 踩坑
    Docker部署文档
    eCharts图形在IE11中不能渲染
    Cookie中文乱码问题
    Blazor Webassembly多标签页实现
  • 原文地址:https://www.cnblogs.com/celine/p/9460878.html
Copyright © 2020-2023  润新知