zoukankan      html  css  js  c++  java
  • java线程之线程同步

    本篇由于涉及多线程操作,所以线程是使用实现Runnable接口来创建的。

    在上篇所示线程任务中,我们不难发现,是存在三步操作的:

    第一:打印语句;

    第二:计算sum=sum-1;

    第三:线程休眠。

    那么,在多线程操作中,可能会出现,第一个线程准备打印,还没有进行sum=sum-1计算时,第二个线程也开始打印语句了,

    那么此时第二个线程打印语句中的sum值由于还没有经过线程1处理,所以线程二打印的语句也会是“还剩49个苹果”,要解决

    这个问题,就引入了线程同步概念,将线程中的所有操作(任务)视为同步处理,是不分先后的。那么,只要线程1比线程2早

    开启,哪怕是1纳秒,线程2中num的初始值也是49,所以线程2输出语句是“还剩48个苹果”,线程同步有三种方法。这里只针对

    具体任务贴出同步代码操作。

    1.同步代码块

     1     public void eat() {
     2         synchronized (this) {
     3             if (sum1 > 0) {
     4                 System.out.println(Thread.currentThread().getName() + "吃了一个苹果," + "还剩" + --sum1 + "个苹果");
     5                 try {
     6                     Thread.sleep(100);
     7                 } catch (InterruptedException e) {
     8                     e.printStackTrace();
     9                 }
    10             }
    11         }
    12     }

    这里的this指向一个同步监听对象,可以理解为一个多线程共享资源,也就是Runnable的实例。

    2.同步方法

     1  synchronized public void eat() {
     2         if (sum1 > 0) {
     3             System.out.println(Thread.currentThread().getName() + "吃了一个苹果," + "还剩" + --sum1 + "个苹果");
     4             try {
     5                 Thread.sleep(100);
     6             } catch (InterruptedException e) {
     7                 e.printStackTrace();
     8             }
     9         }
    10     }

    由于run方法不能用synchronized修饰,只能新建一个该修饰符修饰的方法,放到run里面执行。

    3.同步锁(Lock)

     1     final Lock lock = new ReentrantLock();
     2 
     3     public void eat() {
     4         lock.lock();   //拿锁关门
     5         if (sum1 > 0) {
     6             System.out.println(Thread.currentThread().getName() + "吃了一个苹果," + "还剩" + --sum1 + "个苹果");
     7             try {
     8                 Thread.sleep(100);
     9             } catch (InterruptedException e) {
    10                 e.printStackTrace();
    11             } finally {
    12                 lock.unlock(); //开锁
    13             }
    14         }
    15     }

    这里,先在类里面定义一个锁对象,然后在进入任务之后拿锁锁上,任务结束,开锁,别的线程拿到锁才能进入任务操作。

  • 相关阅读:
    int是逻辑炸弹吗?
    悲剧
    下班啦
    Android SDK 2.2 开发环境安装
    MVC
    用于主题检测的临时日志(61d47e0cd5874842a9f56a725c1f25f6 3bfe001a32de4114a6b44005b770f6d7)
    ASP.NET读取XML文件
    asp.net执行顺序
    理解POCO
    乐观中谨慎 招聘调薪现"贫富差距"
  • 原文地址:https://www.cnblogs.com/eco-just/p/7770435.html
Copyright © 2011-2022 走看看