zoukankan      html  css  js  c++  java
  • 第二十八(线程的同步、守护线程、Timer 定时器)

    /*
        模拟ATM取款,不是线程同步机制,多线程同时对一个账户进行操作
    
        t1 和 t2
        
            异步编程模型:t1线程执行t1,t2线程执行的是t2,两个线程之间谁也不等于谁
            
            同步编程模型:t1线程和t2线程执行,当t1线程必须等于t2的线程执行结果之后,t1线程才能执行
                              这是同步编程模型。
            
            什么时候需要引入同步
                
                1. 为了数据安全,尽管应用程序的使用率低,但是为了保证数据安全性,必须的加入线程同步机制
                
                线程同步机制 使程序变成了(等同)单线程
                
                2. 在什么条件下需要使用线程同步
                    <1> 必须是多线程环境
                    <2> 多线程环境在共享同一个数据时
                    <3> 共享的数据涉及到修改操作 
    
    */
    public class ThreadTest01{
        
        public static void main(String[] args){
            
            // 创建一个公共账户
            Account act = new Account("Ming",10000.0);
            
            // 创建线程对同一个账户进行取款
            Thread t1 = new Thread(new Ming01(act));
            Thread t2 = new Thread(new Ming01(act));
            
            t1.start();
            t2.start();
            
        }
    
    }
    
    // 取款的线程
    class Ming01 implements Runnable{
        
        // Account 账户
        Account act;
        
        Ming01(Account act){
            this.act = act;
        }
        
        public void run(){
            act.withdraw(2000.0);
            System.out.println("取款2000.0¥成功,余额为:" + act.getBalance());
        }
        
    
    }
    
    
    // 银行账户
    class Account{
        
        private String actno;
        private double balance; // 账户余额
        
        public Account(){}
        
        public Account(String actno,double balance){
            this.actno = actno;
            this.balance = balance;
        }
        
        public void setActno(String actno){
            this.actno = actno;    
        }
        public String getActno(){
            return actno;    
        }
    
        public void setBalance(double balance){
            this.balance = balance;    
        }
        public double getBalance(){
            return balance;    
        }
        
        
        
        // 对外提供一个取款方法
        public void withdraw(double money){
            
            // 对账户进行取款操作
            double after = balance - money;
            
            // 延迟
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            
            // 更新账号余额
            this.setBalance(after);
        }
    }
    //输出取款2000.0¥成功,余额为:8000.0
    /*
        以下程序使用线程同步机制保证数据安全型
    
    */
    public class ThreadTest02{
        
        public static void main(String[] args){
            
            // 创建一个公共账户
            Account act = new Account("ming",10000.0);
            
            // 创建线程对同一个账户进行取款
            Thread t1 = new Thread(new Ming01(act));
            Thread t2 = new Thread(new Ming01(act));
            
            t1.start();
            t2.start();
            
        }
    
    }
    
    // 取款的线程
    class Ming01 implements Runnable{
        
        // Account 账户
        Account act;
        
        Ming01(Account act){
            this.act = act;
        }
        
        public void run(){
            act.withdraw(2000.0);
            System.out.println("取款2000.0¥成功,余额为:" + act.getBalance());
        }
        
    
    }
    
    
    // 银行账户
    class Account{
        
        private String actno;
        private double balance; // 账户余额
        
        public Account(){}
        
        public Account(String actno,double balance){
            this.actno = actno;
            this.balance = balance;
        }
        
        public void setActno(String actno){
            this.actno = actno;    
        }
        public String getActno(){
            return actno;    
        }
    
        public void setBalance(double balance){
            this.balance = balance;    
        }
        public double getBalance(){
            return balance;    
        }
        
        
        
        // 对外提供一个取款方法
        public void withdraw(double money){
            
            
            /*
                需要把同步的代码,放到同步的语句块中
                
                t1线程执行到此处,遇到了 synchronized关键字,就会去找this的对象锁
                如果找到了this的对象锁,则进入同步语句块 执行程序。
                当同步语句块代码执行结束的时候,t1线程归还this的对象锁
                
                在t1线程执行同步语句块的过程中,如果t2线程也过来执行以下代码,遇到synchronized关键字
                所以也去找this对象锁,但是该对象被t1线程持有
                只能在等待this对象的归还
            */
    
            synchronized(this){
    
                // 对账户进行取款操作
                double after = balance - money;
                
                // 延迟
                try{
                    Thread.sleep(2000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                
                // 更新账号余额
                this.setBalance(after);
            }
        }
        
    }
    /*
        以下程序使用线程同步机制保证数据安全型
    
    */
    public class ThreadTest03{
        
        public static void main(String[] args){
            
            // 创建一个公共账户
            Account act = new Account("ming",10000.0);
            
            // 创建线程对同一个账户进行取款
            Thread t1 = new Thread(new Ming01(act));
            Thread t2 = new Thread(new Ming01(act));
            
            t1.start();
            t2.start();
            
        }
    
    }
    
    // 取款的线程
    class Ming01 implements Runnable{
        
        // Account 账户
        Account act;
        
        Ming01(Account act){
            this.act = act;
        }
        
        public void run(){
            act.withdraw(2000.0);
            System.out.println("取款2000.0¥成功,余额为:" + act.getBalance());
        }
        
    
    }
    
    
    // 银行账户
    class Account{
        
        private String actno;
        private double balance; // 账户余额
        
        public Account(){}
        
        public Account(String actno,double balance){
            this.actno = actno;
            this.balance = balance;
        }
        
        public void setActno(String actno){
            this.actno = actno;    
        }
        public String getActno(){
            return actno;    
        }
    
        public void setBalance(double balance){
            this.balance = balance;    
        }
        public double getBalance(){
            return balance;    
        }
        
        
        
        // 对外提供一个取款方法
        // synchronized关键字 添加到成员方法上,线程拿走的也是this对象锁
        public synchronized void withdraw(double money){
            
            
            /*
                需要把同步的代码,放到同步的语句块中
                
                t1线程执行到此处,遇到了 synchronized关键字,就会去找this的对象锁
                如果找到了this的对象锁,则进入同步语句块 执行程序。
                当同步语句块代码执行结束的时候,t1线程归还this的对象锁
                
                在t1线程执行同步语句块的过程中,如果t2线程也过来执行以下代码,遇到synchronized关键字
                所以也去找this对象锁,但是该对象被t1线程持有
                只能在等待this对象的归还
            */
    
            //synchronized(this){
    
                // 对账户进行取款操作
                double after = balance - money;
                
                // 延迟
                try{
                    Thread.sleep(2000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                
                // 更新账号余额
                this.setBalance(after);
            //}
        }
        
    }
    /*
        定义一个用户线程
        
    */
    public class UserThread01{
        
        public static void main(String[] args){
            
            Runnable r1 = new UserTest();
            Thread t1 = new Thread(r1,"t1");
            
            t1.start();
            
            for(int i = 0; i < 10; i++){
                System.out.println(Thread.currentThread().getName() + " : " + i);    
            }
            
            System.out.println("主线程结束 !");
            
        }
    
    }
    
    class UserTest implements Runnable{
        
        public void run(){
            for(int i = 0; i < 10; i++){
                System.out.println(Thread.currentThread().getName() + " : " + i);
            }
        }
    
    }
    
    
    /////////////////////////////////////////////////////////////////////////
    
    
    
    /*
        守护线程
        
             其他所有的用户线程结束,则守护线程退出
             守护线程一般都是无限执行的
        
        设置了守护线程以后,当前主线程结束后,守护线程并没有把所有的数据输出就结束
        也就是说 守护线程是为 用户线程服务的,当用户线程全部结束,守护线程会自动结束
        
        跟我们的 java中自动垃圾回收机制GC 是一个原理
        
    */
    public class UserThread02{
        
        public static void main(String[] args){
            
            Thread t1 = new UserTest();
            t1.setName("t1");
            
            // 将t1这个用户线程 修改成守护线程
            t1.setDaemon(true);
            
            t1.start();
            
            // 主线程
            
            for(int i = 0; i < 10; i++){
                System.out.println(Thread.currentThread().getName() + " : " + i);    
                try{
                    Thread.sleep(1000);
                } catch(InterruptedException e){}
            }        
            System.out.println("主线程结束 !");
        
        }
    
    }
    
    class UserTest extends Thread{
        
        public void run(){
            int i = 0;
            while(true){
                i ++;
                System.out.println(Thread.currentThread().getName() +"  : "+i);
                try{
                    Thread.sleep(1000);
                } catch(InterruptedException e){
                    
                }
            }    
        }
    
    }
    /*
        Timer定时器
    
    */
    
    import java.util.*;
    import java.text.*;
    
    public class TimerTest{
        
        public static void main(String[] args){
            Timer t = new Timer();
            try{
            
                Date d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2015-1-20 23:35:30");
                // 安排在指定的时间执行指定的任务
                // t.schedule(new MyTimer(),d,1000*60*60*24); 24小时执行一次
                 t.schedule(new MyTimer(),d,1000*2);
            
            } catch(NullPointerException e){
                e.printStackTrace();
            } catch(IllegalArgumentException e){
                e.printStackTrace();    
            } catch(IllegalStateException e){
                e.printStackTrace();        
            } catch(ParseException e){
                e.printStackTrace();    
            }
        }
    
    }
    
    
    class MyTimer extends TimerTask{
        
        public void run(){
            System.out.println(new Date());    
        }
    
    }
  • 相关阅读:
    c++标准库cstring文件
    c++标准库string文件
    c++标准库cmath文件
    micro:bit用蜂鸣器制作计时器
    【Python入门自学笔记专辑】——PythonUnicode字符
    eclips安装教程
    题目(18)答案
    Console.Write格式化输出
    图像传输有用到,图像与数据流相互转换
    datalist、repearter、gridview显示行号的三种方法 或者是获取datalist行id
  • 原文地址:https://www.cnblogs.com/Deng1185246160/p/4235002.html
Copyright © 2011-2022 走看看