• 6.11Java多线程、并发、同步、synchronized块


    6.11Java多线程、并发、同步、synchronized块

    synchronized块

    • 同步块:synchronized(object){},object称为同步监视器

      • object可以是任何对象,但是推荐使用共享资源作为同步监视器

      • 同步方法中无需指定同步监视器(因为监视对象是this对象本身或者class类的模子)

    • 同步监视器的执行过程

      • 第一个线程访问,锁定同步监视器,执行代码

      • 第二个线程访问,同步监视器被锁定,无法访问

      • 第一个线程访问完毕,解锁同步监视器

      • 第二个线程访问,发现同步监视器未锁,锁定并访问

    synchronized块可以锁定具体的一个对象

    Java当中的四种块

    • 方法当中的块--->局部块

      • 解决变量的作用域--->快速释放内存

    • 类中的块(方法外)--->构造块

      • 初始化对象信息--->对象的信息

    • 静态块(static)

      • 只加载一次

      • 初始化类

      • 先于构造块执行--->类的信息

    • 同步块--->在方法中,解决线程安全的问题--->加一个synchronized、监视对象

      • 推荐使用共享资源作为同步监视器--->只有共享的资源才可能会被多线程访问

    四种块

    使用synchronized同步对象锁,锁定方法保证线程安全
    package iostudy.synchro;

    public class SynBlockTestNo1 {
       public static void main(String[] args) {

           /*资源类对象*/
           AccountTest accountTest = new AccountTest(100, "Money");

           /*线程对象*/
           SynDrawing you = new SynDrawing(accountTest, 80, "JunkingBoy");
           SynDrawing she = new SynDrawing(accountTest, 90, "Lucifer");
           you.start();
           she.start();

      }
    }

    /**
    * 模拟提款机提款类--->多线程
    * @since JDK 1.8
    * @date 2021/6/10
    * @author Lucifer
    */
    class SynDrawing extends Thread{

       /*创建实现类对象--->面向对象的思想*/
       AccountTest accountTest; //取出的账户
       int drawingMoney; //取出的钱数
       int pocketTotal; //取出的钱的总数

       /*创建构造器,将属性定义为参数*/
       public SynDrawing(AccountTest accountTest, int drawingMoney, String name) {
           super(name); //线程的名称
           this.accountTest = accountTest;
           this.drawingMoney = drawingMoney;
      }

       /*重写run方法--->线程的具体实现*/
       @Override
       public void run() {
           test();
      }

       /*
       使用同步块锁定线程
        */
       public void test(){

           /*如果金额为0,结束方法*/
           if (accountTest.money<=0){
               return;
          }

           /*使用同步块锁定线程*/
           synchronized (accountTest){

               /*在存钱和取钱的时候加入条件*/
               if (accountTest.money-drawingMoney<0){
                   /*结束方法*/
                   return;
              }

               /*模拟取款的网络延迟*/
               try {
                   Thread.sleep(1000);
              }catch (InterruptedException e){
                   System.out.println(e.getMessage());
                   e.printStackTrace();
              }
           /*
           理论上说加了判断就会控制结果
           但是实际上不会,这个需要对资源+锁实现控制的效果
            */

               /*账户的金额-取出的金额*/
               accountTest.money -= drawingMoney;
               /*口袋中的金额+取出的钱*/
               pocketTotal += drawingMoney;

               /*因为继承了父类所以可以直接用this--->获取线程的名称*/
               System.out.println(this.getName() + "--->账户余额为:" + accountTest.money);
               System.out.println(this.getName() + "--->身上余额为:" + pocketTotal);

          }
      }
       /*
       假设账户没有金额了,其他进来访问还是需要等待
       所以在等待之前加入一个判断
       这样可以提高并发量--->性能就是从小细节当中调优的
        */
    }
    demo2--->容器中添加同步锁(synchronized)
    package iostudy.synchro;

    import java.util.ArrayList;
    import java.util.List;

    /**
    * 操作容器:
    * 1、这里面没有方法,要思考锁的对象
    * 2、保证安全要思考锁定的范围
    * @since JDK 1.8
    * @date 2021/6/11
    * @author Lucifer
    */
    public class SynBlockTestNo2 {
       public static void main(String[] args) throws InterruptedException{

           /*创建容器*/
           List<String> list = new ArrayList<String>();
           /*循环添加一万个线程*/
           for (int i=0; i<10000; i++){
               new Thread(() -> {

                   /*加一个对象锁,保证线程的准确性*/
                   //同步块,保证线程安全
                   synchronized(list){
                       list.add(Thread.currentThread().getName());
                  }
              }).start();
          }

           /*线程等待*/
           Thread.sleep(10000);
           System.out.println(list.size());

      }
    }

     

    It's a lonely road!!!
  • 相关阅读:
    IList和DataSet性能差别 转自 http://blog.csdn.net/ilovemsdn/article/details/2954335
    jquery click嵌套 事件重复注册 多次执行的问题解决
    IIS MVC 发布错误 403.14Forbidden Web 服务器被配置为不列出此目录的内容
    利用contextmenu事件,自定义右键
    js里面是没有Trim()这个方法的可以用以下的形式来判断是否输入的值为空
    flash的TotalFrames显示undefined
    复习重载
    PHP访问父类中的方法
    复习继承已有的类
    PHP继承已有的类
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/14878078.html
Copyright © 2020-2023  润新知