zoukankan      html  css  js  c++  java
  • 2020年9月12日 线程的安全问题:线程使用共享数据 产生的安全问题

    package com.atguigu.test09;
    
    /*
     * 举例:卖票
     * 假设,有10张票,分三个窗口同时卖
     * 
     * 1、线程安全问题:
     *     当多个线程使用“共享数据”时,就会有线程安全问题。
     *     当一个线程修改了“共享数据”,是会影响其他线程。
     * 
     * 2、如何解决?
     *     加锁
     * 
     * 形式一:同步代码块
     * 形式二:同步方法
     * 
     * 3、同步代码块
     * 语法格式:
     * synchronized(锁对象){
     *         需要加锁的代码
     * }
     * 
     * 锁对象,又称为监视器对象,同一时刻,某一段代码,只允许一个线程运行,这个锁就记录谁现在在运行,其他线程进不来。
     * 
     * 锁对象的选择:
     * (1)可以是任意类型的对象
     * (2)必须是这几天线程要使用同一个锁对象
     * 
     * 锁的代码的范围的选择:
     * (1)太大了:不行
     * (2)太小了:不行
     * 锁一次任务
     */
    public class Test09 {
        public static void main(String[] args) {
            Ticket t1 = new Ticket("窗口一");
            Ticket t2 = new Ticket("窗口二");
            Ticket t3 = new Ticket("窗口三");
            
            t1.start();
            t2.start();
            t3.start();
        }
    }
    class Ticket extends Thread{
        private static int total = 1000;
        private static Object lock = new Object();//锁的选择之一,单独造一个锁对象
        
        public Ticket(String name) {
            super(name);
        }
    
        public void run(){
        //    synchronized (this) {//这里使用this不行,因为这个this,对于三个线程来说不是同一个
            while(true){
                synchronized (lock) {
                    if(total > 0){
                        System.out.println(getName() + "卖出一张票");
                        total--;
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("剩余:" + total);
                    }else{
                        break;
                    }
                }
            }
        }
    }
    package com.atguigu.test10;
    
    /*
     * 步骤:
     * (1)编写线程类,实现Runnable
     * (2)重写run
     * (3)创建线程对象
     * (4)启动线程
     */
    public class Test10 {
        public static void main(String[] args) {
            Ticket t = new Ticket();
            
            Thread t1 = new Thread(t,"窗口一");
            Thread t2 = new Thread(t,"窗口二");
            Thread t3 = new Thread(t,"窗口三");
            
            t1.start();
            t2.start();
            t3.start();
        }
    }
    class Ticket implements Runnable{
        private int total = 10;
    
        @Override
        public void run() {
            while(true){
                synchronized (this) {//选择this当锁,可以,因为只有一个Ticket的对象
                    if(total>0){
                        System.out.println(Thread.currentThread().getName() +"卖出一张票");
                        total--;
                        System.out.println("剩余:" + total);
                    }else{
                        break;
                    }
                }
            }
        }
        
    }
  • 相关阅读:
    Android深度探索-卷1 第三章
    Android深度探索-卷1 第四章
    Android深度探索-卷1 第二章
    Android深度探索-卷1 第一章
    硬件抽象层HAL
    嵌入式Linux调试技术
    蜂鸣器驱动
    控制发光二极管
    搭建S3C6410开发板的测试环境
    统计单词个数
  • 原文地址:https://www.cnblogs.com/douyunpeng/p/13655971.html
Copyright © 2011-2022 走看看