zoukankan      html  css  js  c++  java
  • synchronized站点抢票同步例题


    多线程环境安全问题的判断标准(一定要三个同时满足)
    是否是多线程环境
    是否有共享数据

    是否有多条语句操作(修改)共享数据

    为什么出问题:
    CPU的一次操作必须是原子性的,在一个时间点,CPU只能执行一条指令,而一条语句是由多条指令组成的,比如说i++指令,CPU要先执行i+1,然后将i+1的值赋给i,然后再输出。我们用一条语句来理解,比如下面的卖票程序,当A站点输出语句“A站点还剩88张票”,这个时候还没执行到i--语句,这是B站点抢占到CPU,因为i--还没有执行,B站点也会输出“B站点还剩88张票”,这就出现了线程安全问题。

    线程方法:

    public final int getPriority()  回去当前线程名
    public final void setPriority(int newPriority)  设定当前线程名

    public static void sleep(long millis) 线程休眠

    public final void join() 线程加入  意思是加入的线程优先运行,运行结束后才会轮到下一个线程   注意:必须先开启该线程才能加入线程

    public static void yield()  线程礼让 目的时尚线程抢占更加均衡

    public final void setDaemon(boolean on)  后台线程:守护线程,精灵线程

    public final void stop():中断线程  不建议使用
    public void interrupt(): 中断线程

     如何正确地停止一个线程?

    A:①、使用退出标志,使线程正常退出,也就是当 run 方法完成后线程终止;
    ②、使用 interrupt 方法中断线程
    ③、使用 stop 方法强行终止,但是不推荐使用,因为 stop 和 suspend 以及 resume 一样存在死锁威胁,并且都是过期作废的方法。

    第一种,继承Thread创建多线程,同步方法,静态锁obj对象,使用同步代码块。  

    两者不同点红色标注

    public class MyThread extends Thread{
        static int i=100 ;
        static Object obj=new Object();
        
        public MyThread() {
            super();
        }
        public MyThread(String name) {    
            super(name);
        }
    
        @Override
        public void run() {
            while(i>0){
                synchronized (obj) {//obj对象必须静态,否则两个对象调用的obj不相同,必须保证只有一把锁
                    System.out.println(Thread.currentThread().getName()+"抢到票,还剩"+i+"张票");
                    i--;
                }
            }
        }
    }
    
    public class ThreadTest {
    public static void main(String[] args) {
        MyThread thread1 = new MyThread("A站点");
        MyThread thread2 = new MyThread("B站点");
        thread1.start();
        thread2.start();
    }
    }
    执行结果
    B站点抢到票,还剩100张票
    A站点抢到票,还剩99张票
    A站点抢到票,还剩98张票
    A站点抢到票,还剩97张票
    A站点抢到票,还剩96张票
    A站点抢到票,还剩95张票
    A站点抢到票,还剩94张票
    A站点抢到票,还剩93张票
    A站点抢到票,还剩92张票
    A站点抢到票,还剩91张票
    A站点抢到票,还剩90张票
    A站点抢到票,还剩89张票
    A站点抢到票,还剩88张票
    A站点抢到票,还剩87张票
    A站点抢到票,还剩86张票
    A站点抢到票,还剩85张票
    A站点抢到票,还剩84张票
    A站点抢到票,还剩83张票
    A站点抢到票,还剩82张票

    第二种 实现runnable接口

     1 public class MyRunnable implements Runnable {
     2     int i=100;
     3     Object obj =new Object();
     4     @Override
     5     public void run() {
     6         while(i>0) {
     7              //因为线程虽然有两个 但是多态得到的子类对象只有一个 所以不用静态obj 
     8             //在这里使用代码块而不使用同步关键字修饰方法是因为同步方法,那一个对象会把这个方法执行完才会跳出循环,那就没票了
     9             //使用obj和this是一个意思
    10             synchronized(this) { 
    11                 System.out.println(Thread.currentThread().getName()+"抢到票,还剩"+i+"张票");
    12                 i--;
    13                 try {
    14                     Thread.sleep(100);//加个休眠模拟网络延迟,不知道为什么不加休眠一个线程能抢光所有的票
    15                 } catch (InterruptedException e) {
    16                     // TODO Auto-generated catch block
    17                     e.printStackTrace();
    18                 }
    19             }
    20         }
    21     }
    22 }
    23 
    24 public static void main(String[] args) {
    25     MyRunnable runnable =new MyRunnable();
    26     Thread thread1 = new Thread(runnable,"A站点");
    27     Thread thread2 = new Thread(runnable,"B站点");
    28     thread2.start();
    29     thread1.start();
    30 }
    31 }
  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/19322li/p/10698815.html
Copyright © 2011-2022 走看看