• Java—买票窗口


    线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。


    方式一:使用Runnable接口

    /**
     * 例子:创建三个窗口买票,总票数为100张 ——> 使用实现Runnable接口的方式
     */
    class Window1 implements Runnable{
        private int ticket = 10000;
    
        @Override
        public void run() {
    
            while(true){
    
                if(ticket > 0){
                    System.out.println(Thread.currentThread().getName() + ":买票,票号为:" + ticket);
                    ticket--;
                }else {
                    break;
                }
    
            }
    
        }
    }
    
    public class WindowTest {
        public static void main(String[] args) {
            Window1 w = new Window1();
    
            Thread t1 = new Thread(w);
            Thread t2 = new Thread(w);
            Thread t3 = new Thread(w);
    
            t1.setName("窗口1");
            t2.setName("窗口2");
            t3.setName("窗口3");
    
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    方式二:使用线程同步机制(线程安全处理Synchronized,只有一个锁)

    线程同步的方式有两种:

      方式1:同步代码块

      方式2:同步方法


    使用同步代码块

    public class ThreadTest {
    	public static void main(String[] args) {
    		Ticket t = new Ticket();
    		
    		Thread th1 = new Thread(t);
    		Thread th2 = new Thread(t);
    		Thread th3 = new Thread(t);
    		
    		th1.setName("窗口1");
    		th2.setName("窗口2");
    		th3.setName("窗口3");
    		
    		th1.start();
    		th2.start();
    		th3.start();
    	}
    }
    
    class Ticket implements Runnable{
    	// 定义票根
    	int ticket = 100;
    
    
    	Object lock = new Object();
    	@Override
    	public void run() {
    
    		while(true){
    			
    			// synchronized中的的参数可以为任意对象
    			synchronized (lock) {
    				if(ticket > 0){
    					// 模拟选座的操作
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					
    					System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket);
    					ticket--;
    				}else{
    					break;
    				}
    			}
    			
    		}
    		
    	}
    	
    }
    

    使用同步方法

    public class ThreadTest {
    	public static void main(String[] args) {
    		Ticket t = new Ticket();
    		
    		Thread th1 = new Thread(t);
    		Thread th2 = new Thread(t);
    		Thread th3 = new Thread(t);
    		
    		th1.setName("窗口1");
    		th2.setName("窗口2");
    		th3.setName("窗口3");
    		
    		th1.start();
    		th2.start();
    		th3.start();
    	}
    }
    
    class Ticket implements Runnable{
    	// 定义票根
    	int ticket = 100;
    
    	@Override
    	public void run() {
    		while(true){
    			// 同步方法
    			boolean method = method();
    			if(method){
    				break;
    			}
    		}
    	}
    	
    	// 同步方法中的锁对象是 this
    	// 静态同步方法中的锁对象是 类名.class
    	public synchronized boolean method() {
    		boolean flag = false;
    		
    		if(ticket > 0){
    			// 模拟选座的操作
    			try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			
    			System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket);
    			ticket--;
    		}else{
    			flag = true;
    		}
    		
    		return flag;
    	}
    	
    }
    
  • 相关阅读:
    cmd启动数据库时,出现 (无法启动此程序,因为计算机中丢失VCRUNTIME140_1.dll 尝试重新安装此程序以解决此问题 )解决方法。
    浅谈Promise语法API+封装
    浅谈JS回调地狱
    MySQL数据库安装步骤
    将MongoDB安装为Windows服务---安装MongoDB服务
    后缀.msc文件是什么?
    Mongoose类库使用教程---实现增删改查
    MongoDB可视化工具--Robo 3T 安装使用教程
    久违的锻炼
    出差(2~十四)
  • 原文地址:https://www.cnblogs.com/nadou/p/13984451.html
Copyright © 2020-2023  润新知