Java 线程同步详解

 更新时间:2016年03月24日 10:35:59   作者:赵杰A-124  
这篇文章主要给大家详细介绍的是Java 线程同步的相关问题及代码示例,有需要的小伙伴可以参考下

Java 线程同步根本上是要符合一个逻辑:加锁------>修改------>释放锁

1、同步代码块

示例如下:

public class SyncBlock {
  static class DataWrap {
    int i;
  }
  
  static class SyncBlockThread extends Thread {
    private DataWrap date;
    
    public SyncBlockThread(DataWrap dataWrap) {
      this.date = dataWrap;
    }
    
    @Override
    public void run() {
      
      for (int i = 0; i < 10; i++) {
        synchronized (date) {
          date.i++;
          try {
            sleep(1);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println(getName() + " " + date.i);
        }
      }
    }
  }
  
  public static void main(String[] args) {
    //多线程实现变量i依次加一输出
    DataWrap dataWrap = new DataWrap();
    
    new SyncBlockThread(dataWrap).start();
    new SyncBlockThread(dataWrap).start();
    new SyncBlockThread(dataWrap).start();
  }

}

示例中希望按照顺序依次输出整数。

通常同步代码块是需要锁定的对象,一般是需要并发访问的共享资源,任何线程在修改指定资源之前都首先对该资源加锁,在加锁期间其它线程无法修改该资源。从而保证了线程的安全性。另外线程在调用sleep或者yield时并不会让出资源锁。

2、同步方法

public class SyncMethod {
  
  static class DataWrap{
    int i;
    
    public synchronized void valueGrow(){
      i++;
      
      try {
        Thread.sleep(1);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      System.out.println(Thread.currentThread().getName() + " " + i);
    }
  }
  
  static class SyncMethodThread extends Thread {
    DataWrap dataWrap;
    
    public SyncMethodThread(DataWrap dataWrap){
      this.dataWrap = dataWrap;
    }
    
    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
        dataWrap.valueGrow();  
      }
    }
  }
  
  public static void main(String[] args) {
    //实现顺序增长并输出Datawrap中的i
    
    DataWrap dataWrap = new DataWrap();
    
    new SyncMethodThread(dataWrap).start();
    new SyncMethodThread(dataWrap).start();
    new SyncMethodThread(dataWrap).start();
  }

}

同步方法是使用synchronized关键字修饰的某个方法,同步方法锁定的就是该对象本身,所以当一个线程调用了某个对象的同步方法后,如有其它线程调用该对象的其它同步方法,也依然要等待释放该对象的锁,因为该对象已被锁定。

3、同步锁

通过定义同步锁对象实现同步,这种情况下,同步锁使用Lock对象充当。

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SyncLock {

  static class DataWrap{
    Lock lock = new ReentrantLock();
    int i;
    
    public void valueGrow(){
      lock.lock();
      try {
        i++;
        
        try {
          Thread.sleep(1);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " " + i);  
      } finally {
        lock.unlock();
      }
      
    }
  }
  
  static class SyncLockThread extends Thread {
    DataWrap dataWrap;
    
    public SyncLockThread(DataWrap dataWrap){
      this.dataWrap = dataWrap;
    }
    
    @Override
    public void run() {
      for (int i = 0; i < 10; i++) {
        dataWrap.valueGrow();  
      }
    }
  }
  
  public static void main(String[] args) {
    //实现顺序增长并输出Datawrap中的i
    
    DataWrap dataWrap = new DataWrap();
        
    new SyncLockThread(dataWrap).start();
    new SyncLockThread(dataWrap).start();
    new SyncLockThread(dataWrap).start();
  }

}

使用锁对象实现线程同步会更灵活一些,某些锁还具有一些特定的功能,其中比较常用的ReadWriteLock读写锁,ReentrantLock可重入锁。

相关文章

  • java实现学生信息录入界面

    java实现学生信息录入界面

    这篇文章主要为大家详细介绍了java实现学生信息录入界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Java编程异常简单代码示例

    Java编程异常简单代码示例

    这篇文章主要介绍了Java编程异常简单代码示例,还是比较不错的,这里分享个大家,需要的朋友可以参考下。
    2017-11-11
  • Java中替代equals,compareTo和toString的方法

    Java中替代equals,compareTo和toString的方法

    这篇文章主要介绍了Java中替代equals,compareTo和toString的方法,文中代码十分详细,帮助大家更好的理解的学习,感兴趣的朋友可以了解下
    2020-06-06
  • 在编码时如何使用\r与\n,两者的区别

    在编码时如何使用\r与\n,两者的区别

    本篇文章是对\r与\n两者的区别,以及编程语言中如何使用进行了详细的分析介绍,需要的朋友可以参考下
    2015-07-07
  • Spring Boot集成Druid查看配置是否生效的方法

    Spring Boot集成Druid查看配置是否生效的方法

    本文主要介绍了Spring Boot集成Druid查看配置是否生效的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 解决java.net.SocketTimeoutException: Read timed out的问题

    解决java.net.SocketTimeoutException: Read timed out的问题

    这篇文章主要介绍了解决java.net.SocketTimeoutException: Read timed out的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 关于解决雪花算法生成的ID传输前端后精度丢失问题

    关于解决雪花算法生成的ID传输前端后精度丢失问题

    这篇文章主要介绍了关于解决雪花算法生成的ID传输前端后精度丢失问题,雪花算法生成的ID传输到前端时,会出现后三位精度丢失,本文提供了解决思路,需要的朋友可以参考下
    2023-03-03
  • java读写串口数据你了解多少

    java读写串口数据你了解多少

    这篇文章主要为大家详细介绍了java读写串口数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • 使用socket实现网络聊天室和私聊功能

    使用socket实现网络聊天室和私聊功能

    这篇文章主要介绍了使用socket实现网络聊天室和私聊功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • spring动态注册bean AOP失效原理解析

    spring动态注册bean AOP失效原理解析

    这篇文章主要为大家介绍了spring动态注册bean使AOP失效原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07

最新评论