当前位置:   article > 正文

java多线程资源竞争_java多个线程同时new对象存在竞争的情况会发生什么

java多个线程同时new对象存在竞争的情况会发生什么
  1. 先看一下java多线程资源竞争的案例
/* 当多个线程访问同一个变量时,这个变量被称为共享变量,而当多个线程操作同一个变量时,就会出现资源竞争的问题,
* 举例, 有个变量num为100, 每个线程对其的操作就是减去1(想想一下卖票系统,100个票,有三个售票员[三个线程]),有一个
*  在cpu哪里累死累活抢到了使用权,拿到了100,还没来的及去减1, 完了,cpu被第二只线程抢了过去,一看num还是100,然后执行了100-1
*  num就这样变为了99,这时第一个cpu终于抢到了cpu的使用权,去吧num减1,这一减不要紧,num也变成了99,这样,100这支票被卖出去了两
*  此,那这问题就出现了,票卖重了,这是谁的锅? 或者当卖到最后一张票时,还很容易造成超卖现象
* */

import javax.sql.rowset.spi.SyncFactory;

public class Demo26Class implements Runnable {
    private int num1;
    Object obj = new Object();

    Demo26Class(){

    }

    Demo26Class(int num){
        this.num1 = num;
    }

    @Override
    public void run() {

        while (true) {

            if (num1 > 0){
                // 添加延迟时间,可以更好的看出资源竞争
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "售出车票第" + num1-- + "张");
            }
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
// 调用线程共享, 注意,资源竞争不是说创建很多对象,而是一个对象中的多个线程对资源的竞争,比如下面代码中objClass1的对象
// 而不是在new一个对象objClass2,然后再start

public class Demo27Class {

    public static void main(String[] args) {
        int num = 20;
        Demo26Class objClass1 = new Demo26Class(num);
        new Thread(objClass1, "售票车窗1").start();
        new Thread(objClass1, "售票车窗2").start();
        new Thread(objClass1, "售票车窗3").start();
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

执行结果:

售票车窗2售出车票第19张
售票车窗3售出车票第18张
售票车窗1售出车票第20张
售票车窗2售出车票第17张
售票车窗1售出车票第15张
售票车窗3售出车票第16张
售票车窗2售出车票第13张
售票车窗3售出车票第12张
售票车窗1售出车票第14张
售票车窗1售出车票第10张
售票车窗3售出车票第11张
售票车窗2售出车票第9张
售票车窗1售出车票第8张
售票车窗3售出车票第6张
售票车窗2售出车票第7张
售票车窗2售出车票第5张
售票车窗1售出车票第5张
售票车窗3售出车票第5张
售票车窗1售出车票第3张
售票车窗3售出车票第4张
售票车窗2售出车票第2张
售票车窗1售出车票第1张
售票车窗3售出车票第0张
售票车窗2售出车票第-1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  1. 解决方案一:同步代码块 synchronized()
/* 当多个线程访问同一个变量时,这个变量被称为共享变量,而当多个线程操作同一个变量时,就会出现资源竞争的问题,
* 举例, 有个变量num为100, 每个线程对其的操作就是减去1(想想一下卖票系统,100个票,有三个售票员[三个线程]),有一个
*  在cpu哪里累死累活抢到了使用权,拿到了100,还没来的及去减1, 完了,cpu被第二只线程抢了过去,一看num还是100,然后执行了100-1
*  num就这样变为了99,这时第一个cpu终于抢到了cpu的使用权,去吧num减1,这一减不要紧,num也变成了99,这样,100这支票被卖出去了两
*  此,那这问题就出现了,票卖重了,这是谁的锅? 或者当卖到最后一张票时,还很容易造成超卖现象
* */

import javax.sql.rowset.spi.SyncFactory;

public class Demo26Class implements Runnable {
    private int num1;
    Object obj = new Object();

    Demo26Class(){

    }

    Demo26Class(int num){
        this.num1 = num;
    }

    @Override
    public void run() {

        while (true) {
            // obj 是一个对象
            synchronized(obj){
                if (num1 > 0){
                    // 添加延迟时间,可以更好的看出资源竞争
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "售出车票第" + num1-- + "张");
                }
            }
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

执行结果:

售票车窗1售出车票第20张
售票车窗1售出车票第19张
售票车窗1售出车票第18张
售票车窗1售出车票第17张
售票车窗1售出车票第16张
售票车窗1售出车票第15张
售票车窗1售出车票第14张
售票车窗1售出车票第13张
售票车窗1售出车票第12张
售票车窗1售出车票第11张
售票车窗1售出车票第10张
售票车窗1售出车票第9张
售票车窗1售出车票第8张
售票车窗1售出车票第7张
售票车窗1售出车票第6张
售票车窗1售出车票第5张
售票车窗1售出车票第4张
售票车窗3售出车票第3张
售票车窗2售出车票第2张
售票车窗2售出车票第1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 解决方案二:同步函数 synchronized, 这里以静态方法演示
/* 当多个线程访问同一个变量时,这个变量被称为共享变量,而当多个线程操作同一个变量时,就会出现资源竞争的问题,
* 举例, 有个变量num为100, 每个线程对其的操作就是减去1(想想一下卖票系统,100个票,有三个售票员[三个线程]),有一个
*  在cpu哪里累死累活抢到了使用权,拿到了100,还没来的及去减1, 完了,cpu被第二只线程抢了过去,一看num还是100,然后执行了100-1
*  num就这样变为了99,这时第一个cpu终于抢到了cpu的使用权,去吧num减1,这一减不要紧,num也变成了99,这样,100这支票被卖出去了两
*  此,那这问题就出现了,票卖重了,这是谁的锅? 或者当卖到最后一张票时,还很容易造成超卖现象
* */

import javax.sql.rowset.spi.SyncFactory;

public class Demo26Class implements Runnable {
    private static int num1 = 20;

    @Override
    public void run() {
        demoDef1();

    }

    public static synchronized void demoDef1(){
        while (true) {
            if (num1 > 0){
                // 添加延迟时间,可以更好的看出资源竞争
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "售出车票第" + num1-- + "张");
            }

        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
// 调用线程共享, 注意,资源竞争不是说创建很多对象,而是一个对象中的多个线程对资源的竞争,比如下面代码中objClass1的对象
// 而不是在new一个对象objClass2,然后再start

public class Demo27Class {

    public static void main(String[] args) {

        Demo26Class objClass1 = new Demo26Class();
        new Thread(objClass1, "售票车窗1").start();
        new Thread(objClass1, "售票车窗2").start();
        new Thread(objClass1, "售票车窗3").start();


    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
售票车窗1售出车票第20张
售票车窗1售出车票第19张
售票车窗1售出车票第18张
售票车窗1售出车票第17张
售票车窗1售出车票第16张
售票车窗1售出车票第15张
售票车窗1售出车票第14张
售票车窗1售出车票第13张
售票车窗1售出车票第12张
售票车窗1售出车票第11张
售票车窗1售出车票第10张
售票车窗1售出车票第9张
售票车窗1售出车票第8张
售票车窗1售出车票第7张
售票车窗1售出车票第6张
售票车窗1售出车票第5张
售票车窗1售出车票第4张
售票车窗1售出车票第3张
售票车窗1售出车票第2张
售票车窗1售出车票第1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  1. 解决方案三:建立锁(推荐使用)
/* 当多个线程访问同一个变量时,这个变量被称为共享变量,而当多个线程操作同一个变量时,就会出现资源竞争的问题,
* 举例, 有个变量num为100, 每个线程对其的操作就是减去1(想想一下卖票系统,100个票,有三个售票员[三个线程]),有一个
*  在cpu哪里累死累活抢到了使用权,拿到了100,还没来的及去减1, 完了,cpu被第二只线程抢了过去,一看num还是100,然后执行了100-1
*  num就这样变为了99,这时第一个cpu终于抢到了cpu的使用权,去吧num减1,这一减不要紧,num也变成了99,这样,100这支票被卖出去了两
*  此,那这问题就出现了,票卖重了,这是谁的锅? 或者当卖到最后一张票时,还很容易造成超卖现象
* */

import javax.sql.rowset.spi.SyncFactory;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Demo26Class implements Runnable {
    private static int num1 = 20;
    // 创建一把锁
    Lock lock1 = new ReentrantLock();

    @Override
    public void run() {

        while (true) {
            // 上锁
            lock1.lock();
            if (num1 > 0){
                // 添加延迟时间,可以更好的看出资源竞争
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "售出车票第" + num1-- + "张");
            }
            // 解锁
            lock1.unlock();
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
// 调用线程共享, 注意,资源竞争不是说创建很多对象,而是一个对象中的多个线程对资源的竞争,比如下面代码中objClass1的对象
// 而不是在new一个对象objClass2,然后再start

public class Demo27Class {

    public static void main(String[] args) {

        Demo26Class objClass1 = new Demo26Class();
        new Thread(objClass1, "售票车窗1").start();
        new Thread(objClass1, "售票车窗2").start();
        new Thread(objClass1, "售票车窗3").start();


    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

执行结果:

售票车窗1售出车票第20张
售票车窗1售出车票第19张
售票车窗1售出车票第18张
售票车窗1售出车票第17张
售票车窗1售出车票第16张
售票车窗1售出车票第15张
售票车窗1售出车票第14张
售票车窗1售出车票第13张
售票车窗1售出车票第12张
售票车窗1售出车票第11张
售票车窗1售出车票第10张
售票车窗1售出车票第9张
售票车窗1售出车票第8张
售票车窗1售出车票第7张
售票车窗1售出车票第6张
售票车窗1售出车票第5张
售票车窗1售出车票第4张
售票车窗1售出车票第3张
售票车窗1售出车票第2张
售票车窗1售出车票第1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/341710
推荐阅读
相关标签
  

闽ICP备14008679号