精华内容
下载资源
问答
  • java对文件加锁

    2016-11-23 19:24:00
    文件操作过程中,有时候需要文件进行加锁操作,...文件的加锁方法有两种: 第一种方法:使用RandomAccessFile类操作文件。 在java.io.RandomAccessFile类的open方法,提供了参数实现独占的方式打开文件:  ...

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt208

    在对文件操作过程中,有时候需要对文件进行加锁操作,防止其他线程访问该文件。对文件的加锁方法有两种:

    第一种方法:使用RandomAccessFile类操作文件。

    在java.io.RandomAccessFile类的open方法,提供了参数实现独占的方式打开文件:

            RandomAccessFile raf = new RandomAccessFile(file, "rws");

    其中的“rws”参数,rw代表读取和写入,s代表了同步方式,也就是同步锁。这种方式打开的文件,就是独占方式的。

    第二种方法:使用sun.nio.FileChannel对文件进行加锁。

    代码:

          RandomAccessFile raf = new RandomAccessFile("file.txt", "rw");

          FileChannel fc = raf.getChannel();

          FileLock fl = fc.tryLock();

          if(fl.isValid())

              System.out.println("You have got the file lock.");

    以上是通过RandomAccessFile来获得文件锁的,那么在写文件的时候如何对文件加锁呢?方法如下:

    代码:

            FileOutputStream fos = new FileOutputStream("file.txt");

            FileChannel fc = fos.getChannel(); //获取FileChannel对象

            FileLock fl = fc.tryLock();  //or fc.lock();

            if(null != fl)

                 System.out.println("You have got file lock.");

            //TODO write content to file

            //TODO write end, should release this lock

            fl.release(); //释放文件锁  注意:释放锁要在文件写操作之前,否则会出异常

            fos.close;  //关闭文件写操作

     

    如果在读文件操作的时候,对文件进行加锁,怎么操作呢?从API文档中我们可以看到,FileChannel也可以从FileInputStream中直接获得,但是这种直接获得FileChannel的对象直接去操作FileLock会报异常NonWritableChannelException,这样我们又怎么去获得文件锁呢?需要自己去实现getChannel方法,代码如下:

               private static FileChannel getChannel(FileInputStream fin, FileDescriptor fd) {

                      FileChannel channel = null;

                      synchronized(fin){

                            channel = FileChannelImpl.open(fd, true, true, fin);

                            return channel;

                      }

                }

    其实,我们看FileInputStream时,发现getChannel方法与我们写的代码只有一个地方不同,即open方法的第三个参数不同,如果设置为false,就不能锁住文件了。缺省的getChannel方法,就是false,因此,不能锁住文件。

    展开全文
  • java的静态方法加锁与一般方法加锁

    万次阅读 2018-01-15 20:57:24
    第一部分: synchronized 与static synchronized 的区别 ...第二部分:java多线程锁,源码剖析 ...synchronized是类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块。

    第一部分: synchronized 与static synchronized  的区别


    第二部分:java多线程锁,源码剖析


    1、synchronized与static synchronized 的区别
          synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块。
      static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块。且一个类的所有静态方法公用一把锁。
    如下:
    pulbic class Something(){
    
           public synchronized void isSyncA(){}
    
           public synchronized void isSyncB(){}
    
           public static synchronized void cSyncA(){}
    
           public static synchronized void cSyncB(){}
    
    }

    注解:该列子来自一个日本作者-结成浩的《java多线程设计模式》

    那么,假如有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢

    a.   x.isSyncA()与x.isSyncB() 

    b.   x.isSyncA()与y.isSyncA()

    c.   x.cSyncA()与y.cSyncB()

    d.   x.isSyncA()与Something.cSyncA()

    这里,很清楚的可以判断:

    a,都是对同一个实例的synchronized域访问,因此不能被同时访问

    b,是针对不同实例的,因此可以同时被访问

    c,因为是staticsynchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与   Something.isSyncB()了,因此不能被同时访问。

    那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。

    个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。 后面一部分将详细分析 synchronzied 是怎么样实现的 

    结论 :

    A: synchronized static是某个类的范围,synchronized static cSync{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

    B: synchronized 是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized 方法。

    2、synchronized方法与synchronized代码快的区别        synchronizedmethods(){}与 synchronized(this){}之间没有什么区别,只是 synchronized methods(){} 便于阅读理解,而 synchronized ( this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。

    3 、synchronized

    关键字是不能继承的

    也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;

    4、从源代码详细理解synchronized关键字(参考Observable类源码)

    Java中的Observer模式,看了其中的Observable类的源码,发现里面几乎所有的方法都用了synchronized关键字(不是全部),其中个别用了synchronized(this){}的区块


    第二部分:Java多线程锁,源代码剖析

    多线程的同步依靠的是锁机制,java中可通过 synchronized 关键字锁锁住共享资源以实现异步多线程的达到同步。总结起来,要达到同步,我们要做的就是构造各线程间的 共享资源 ,其中的共享资源可以 对象 ,也可以是 方法 。

    package algorithms.com.guan.zoo.stackTest;
    
    public class LockDemo {
      public static void main(String[] args) {
        MyRunnerVarLock runnerVarLock = new MyRunnerVarLock(new Integer(0));
        MyRunnerFuncLock runnerFuncLock = new MyRunnerFuncLock();
        MyRunnerNoLock runnerNoLock = new MyRunnerNoLock(); 
        
        // 对共享对象进行加锁,线程会依次打印0-99的数,每一次运行的结果都一样
        for(int i = 0; i < 10; i++) {
          Thread thread = new Thread(runnerVarLock);
          thread.start();
        }
        
        // 对共享函数进行加锁,线程会依次打印0-99的数,每一次运行的结果都一样
        for(int i = 0; i < 10; i++) {
          Thread thread = new Thread(runnerFuncLock);
          thread.start();
        }
        
        // 未加锁,会因为线程调用的时序不同而发生变化,每一次运行的结果不一定相同
        for(int i = 0; i < 10; i++) {
          Thread thread = new Thread(runnerNoLock);
          thread.start();
        }
      }
    }
    
    // 对共享对象进行加锁
    class MyRunnerVarLock implements Runnable {
      private Object lock;
    
      public MyRunnerVarLock(Object lock) {
        this.lock = lock;
      }
    
      public void run() {
        synchronized (lock) {
          for (int i = 0; i < 100; i++) {
            System.out.println("Lock: " + i);
          }
        }
      }
    }
    
    // 对共享函数进行加锁
    class MyRunnerFuncLock implements Runnable {
      public synchronized void run() {
        for (int i = 0; i < 100; i++) {
          System.out.println("Func lock: " + i);
        }
      }
    }
    
    // 没有加锁
    class MyRunnerNoLock implements Runnable {
      public void run() {
        for (int i = 0; i < 100; i++) {
          System.out.println("No lock: " + i);
        }
      }
    }






    展开全文
  • 对象加锁方法加锁方法会不会互相阻塞? 今天面试遇到这么一个问题:对象加锁方法加锁方法会不会互相阻塞? 然后我参照了网上的一些博客内容,写了以下程序验证: 他们的结果是交错输出的,...

    Java中对对象加锁的方法和对类加锁的方法会不会互相阻塞?

    今天面试遇到这么一个问题:对对象加锁的方法和对类加锁的方法会不会互相阻塞?

    然后我参照了网上的一些博客内容,写了以下程序验证:

    他们的结果是交错输出的,也就是说他们是不阻塞的。

    那么为什么会成为这样子呢?

    先说一个Synchronized的原理

    Synchronized关键字在编译的时候,会在同步块前后形成一个monitorenter和monitorexit的字节码指令,这两个字节码都需要一个reference类型的参数来指明要加锁和解锁的对象,在执行moniterenter指令的时候,首先要先获取加锁的对象,如果这个对象没有被锁定,就会把对象头里边锁的计数器加1,执行monitroexit的时候就会把锁的对象减一。

    在执行synchronized (Solution.class)进入代码块的时候,他是对Solution的Class对象加锁,Class对象是每次加载Class文件在JVM中生成的对象,每个类对应着一个Class对象,这个Class对象是实际存在的,因此在进入synchronized (Solution.class)同步代码块的时候,会将对象头中锁的计数器加一。对实例对象synchronized (this)进行加锁的时候,则会在实例对象的对象头的计数器里边加一。因此他们是不通的加锁对象,因此不会阻塞。

    那么对使用不同加载器加载的类加锁会不会阻塞呢?

    我正在验证,之后补上。

    结果和程序如下
    image-20211023124503822

    public class Solution3 {
    	
    	static void run1() throws InterruptedException {
    		synchronized (Solution.class) {
    			for(int i=0;i<10;i++) {
    				Thread.sleep(10);
    				System.out.println(Thread.currentThread().getName());
    			}
    		}
    	}
    	void run2() throws InterruptedException {
    		
    		synchronized (this) {
    			for(int i=0;i<10;i++) {
    				Thread.sleep(10);
    				System.out.println(Thread.currentThread().getName());
    			}
    		}
    		
    	}
    	public static void main(String[] args) throws InterruptedException {
    		Solution3 solution=new Solution3();
    		new Thread(()->{
    			try {
    				Solution3.run1();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}).start();
    		
    		new Thread(()->{
    			try {
    				solution.run2();
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}).start();
    		
    		Thread.sleep(2000);
    	}
    }
    
    
    
    
    展开全文
  • synchronized是类的当前实例(当前对象)进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块。每个对象都有一个锁,且是唯一的。 注意: 1.指的是“类的当前实例”, 类的两个不同实例就没有这种...

    对象锁(实例锁,synchronized

    该锁针对的是该实例对象(当前对象)。
    synchronized是对类的当前实例(当前对象)进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块。
    每个对象都有一个锁,且是唯一的

    注意:

    1.指的是“类的当前实例”, 类的两个不同实例就没有这种约束了。

    2.锁住的只是synchronized块,static synchronized块锁不住,而不加锁的方法更加锁不住。

     

    类锁(又称全局锁,static synchronized

    该锁针对的是类,无论实例出多少个对象,那么线程依然共享该锁。
    static synchronized是限制多线程中该类的所有实例同时访问该类所对应的代码块

    注意:

    1.static synchronized并不是关键字,只是代表给静态方法加锁。

    2.锁住的只是static synchronized块,synchronized块锁不住,而不加锁的方法更加锁不住

     

    参考博客:https://www.jianshu.com/p/8327c5c15cb8 

    展开全文
  • 看编程思想一书,也写了段代码,发现static的资源加锁无效,左思右想终于找出了原因,现贴出与大家分享。 import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; class Source {...
  • Java对文件加锁(二)

    千次阅读 2012-12-08 00:35:09
    上一篇文章讲的是文件的加锁,但是在实际的过程中,会产生额外的内存消耗。一个重要的原因是,因为我们是把这些地址和锁存在一个HashMap中的,如果人为不清理的话,这个HashMap里面存放的内容就会越来越多。下面我...
  • 今天小编就为大家分享一篇关于Java双重检查加锁单例模式的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • Java多线程加锁方式

    2020-08-21 00:48:11
    java中要加锁有两种方式 synchronized修饰 jkd中实现java.util.concurrent.locks.Lock接口的类 ReentrantLock ReentrantReadWriteLock
  • java 多线程加锁

    2020-06-09 16:03:32
    java 加锁方法: 1:直接加 synchronized 关键字 2:使用lock private java.util.concurrent.locks.Lock lock = new ReentrantLock(); private void fun(){ lock.lock(); try{ 执行语句...... } ...
  • 主要介绍了java synchronized加载加锁-线程可重入详解及实例代码的相关资料,需要的朋友可以参考下
  • 主要介绍了java多线程加锁以及Condition类的使用实例解析,文中通过示例代码介绍的非常详细,大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • java中static方法加锁

    2014-08-06 14:37:00
    也就是说静态方法加锁是通过Class对象来加锁的 这样也证明了一个类只有一个Class对象,(因为synchronized是通过==来比较的) 转载于:https://my.oschina.net/u/1442901/blog/298538
  • java加锁方法

    千次阅读 2019-07-16 14:33:47
    最直接也是最简单的方法,使用synchronized同步关键字: 使用Lock: ReenTrantLock lock = newReenTrantLock(); private void fun(){ lock.lock(); try{ 执行语句...... ........... } finally{ ...
  • java中Lock加锁操作

    2020-09-22 22:58:46
    加锁后必须解锁 Lock lock=new ReentrantLock(); lock.lock(); try { //do something } catch (Exception e) { //回滚try中的操作或者改成合适的状态值 e.printStackTrace(); }finally { lock.unlock(); ...
  • Synchronized修饰非静态方法,是调用该方法的对象加锁,俗称“对象锁”。 这里的对象加锁并非是说执行该加锁方法的时候整个对象的所有成员都不允许其他线程访问了, 而是说该对象内所有的加锁的非静态方法共用这...
  • Java 多线程加锁的方式

    万次阅读 2018-07-20 09:42:47
    一.Java多线程可以通过: 1. synchronized关键字 2. Java.util.concurrent包中的lock接口和ReentrantLock实现类 这两种方式实现加锁。   二.synchronized关键字加锁的缺陷:   如果一个代码块被synchro...
  • /** * 测试多线程并发获取唯一子增长的值 * @author Administrator * */ public class BB { private int increment = 0; final static Set<Integer> set = new HashSet();... final static List<Integer> list =...
  • JavaString加锁

    千次阅读 2019-09-15 14:47:33
    String类型的值通常存储于常量池或JVM堆中。 字符串变量赋值时,赋值符右边: 1、只有字符串常量,那么变量存放在常量池里面。... 3、字符串进行拼接(+)操作时,分两种情况: A、表达式右边是纯字...
  • java中文件加锁机制

    千次阅读 2013-12-11 20:44:00
    当同时一个文件进行操作的时候,很可能出现错误甚至锁坏文件。 在某些情况下,有一个应用的两个实例同事操作一个文件,第一个实例应该锁定这个文件,第二个实例发现这个文件被锁定,是等待它解锁还是跳过文件操作...
  • 静态方法加锁和非静态方法加锁的区别 静态方法加锁:static ...synchronized是类的当前实例(当前对象)进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, ...
  • java中同步加锁的几种方式

    千次阅读 2013-12-17 14:11:10
    同步加锁的几种方式: 1、使用静态代码块 ...2、对方法进行加锁 public synchronized void add() {} 3、 Integer y = 5;//OK使用一个定值 synchronized (同步加锁.class、y、) {} 4、String s
  • Java 多线程加锁

    千次阅读 2006-09-28 21:07:00
    以前的同步操作 基本上都是用到 synchronised 关键字,类似代码如下:synchronised(obj){//dosomething...}来做到同步,在 JDK5.0 里面有这么一个对象,ReentrantLock,发觉她的加锁编程的方式非常的适合日常的...
  • Java 多线程加锁的方式总结及对比

    万次阅读 多人点赞 2017-03-28 14:27:53
    一.Java多线程可以通过: 1. synchronized关键字 2. Java.util.concurrent包中的lock接口和ReentrantLock实现类 这两种方式实现加锁。 二.synchronized关键字加锁的缺陷: 如果一个代码块被s
  • 我们都知道,java中可以使用synchronized对方法,或者变量加锁,那么,当我们使用synchronized对方法加锁,对变量加锁,shnchronized结合static一起使用,两个普通方法同时调用一个使用synchronized方法等等情况下,...
  • ##synchronized普通方法加锁锁住的是当前对象,如果多个对象同时访问的时候无法保证线程。 ###普通方法加锁 当有一个当有一个对象的时候运行结果:# ###多个对象的运行结果 我们可以发现出现了两次票数为6 ##...
  • 原文地址:http://greemranqq.iteye.com/blog/1974143今天看了到有意思的题:在静态方法加锁 和 非静态方法加锁 有什么区别,从而再次引出锁机制的一些理解。 先看方法:// 这是一个很简单的类,里面共享静态变量...
  • String redisLockKey ="";//自定义 Boolean lockRet = redisTemplate.opsForValue().setIfAbsent(redisLockKey, redisLockKey);// 对应setnx命令 ...//里面写要加锁的内容方法 }else{ re...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 171,331
精华内容 68,532
关键字:

java对方法加锁

java 订阅