有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (6) 个答案

  1. # 1 楼答案

    有很多方法可以做到这一点,但每种方法都包含很多味道。Java8还附带了新的并发特性。 确保线程安全的一些方法有:
    Semaphores
    锁-Reentrantlock,ReadWriteLock,StampedLock(Java 8)

  2. # 2 楼答案

    只有局部方法的变量/引用。或者确保任何实例变量都是不可变的

  3. # 3 楼答案

       ////////////FIRST METHOD USING SINGLE boolean//////////////
    
    
        public class ThreadTest implements Runnable { 
            ThreadTest() {
                Log.i("Ayaz", "Constructor..");
            }
    
            private boolean lockBoolean = false;
    
            public void run() {
                Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
                while (lockBoolean) {
                 // infinite loop for other thread if one is accessing
                }
                lockBoolean = true;
                synchronizedMethod();
            }
    
            /**
             * This method is synchronized without using synchronized keyword
             */
            public void synchronizedMethod() {
                Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
                try {
                    Thread.currentThread().sleep(3000);
                } catch (Exception e) {
                    System.out.println("Exp");
                }
                Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
                lockBoolean = false;
            }
    
        } //end of ThreadTest class
    
         //For testing use below line in main method or in Activity
         ThreadTest threadTest = new ThreadTest();
                Thread threadA = new Thread(threadTest, "A thead");
                Thread threadB = new Thread(threadTest, "B thead");
                threadA.start();
                threadB.start();
    
    ///////////SECOND METHOD USING TWO boolean/////////////////
    
    
    
     public class ThreadTest implements Runnable {
        ThreadTest() {
            Log.i("Ayaz", "Constructor..");
        }
    
        private boolean isAnyThreadInUse = false;
        private boolean lockBoolean = false;
    
        public void run() {
            Log.i("Ayaz", "Thread started.." + Thread.currentThread().getName());
            while (!lockBoolean)
                if (!isAnyThreadInUse) {
                    isAnyThreadInUse = true;
                    synchronizedMethod();
                    lockBoolean = true;
                }
        }
    
        /**
         * This method is synchronized without using synchronized keyword
         */
        public void synchronizedMethod() {
            Log.e("Ayaz", "processing...." + Thread.currentThread().getName());
            try {
                Thread.currentThread().sleep(3000);
            } catch (Exception e) {
                System.out.println("Exp");
            }
            Log.e("Ayaz", "complete.." + Thread.currentThread().getName());
            isAnyThreadInUse = false;
        }
    
    } // end of ThreadTest class
    
         //For testing use below line in main method or in Activity
         ThreadTest threadTest = new ThreadTest();
         Thread t1 = new Thread(threadTest, "a thead");
         Thread t2 = new Thread(threadTest, "b thead");
         t1.start();
         t2.start();
    
  4. # 4 楼答案

    您可以通过使所有数据不可变来确保代码的线程安全,如果没有可变性,那么一切都是线程安全的

    第二,您可能想看看java并发API,它提供了读/写锁,在读写器很多的情况下性能更好。纯同步关键字也会阻止两个读卡器

  5. # 5 楼答案

    实际上,有很多方法:

    1. 如果没有可变状态,就根本不需要同步
    2. 如果可变状态仅限于单个线程,则无需同步。这可以通过使用局部变量或^{}来实现
    3. 也可以使用内置同步器^{}具有与使用synchronized块和方法时访问的锁相同的功能,它甚至更强大
  6. # 6 楼答案

    为了保持可预测性,您必须确保对可变数据的所有访问都是按顺序进行的,或者处理并行访问引起的问题

    最严重的保护使用synchronized关键字。除此之外,至少还有两层可能性,每层都有各自的好处

    锁/信号灯

    这些方法非常有效。例如,如果一个结构被多个线程读取,但只被一个线程更新,那么ReadWriteLock可能会很有用

    如果选择与算法匹配的锁,锁的效率会更高

    原子

    例如,使用AtomicReference通常可以提供完全无锁的功能。这通常会带来巨大的好处

    原子学背后的理由是允许它们失败,但告诉你它们失败的方式是你可以处理的

    例如,如果要更改某个值,可以读取该值,然后写入其新值,只要该值仍然是旧值。这被称为“比较和设置”或cas,通常可以在硬件中实现,因此非常有效。你所需要的就是:

    long old = atomic.get();
    while ( !atomic.cas(old, old+1) ) {
      // The value changed between my get and the cas. Get it again.
      old = atomic.get();
    }
    

    然而,请注意,可预测性并不总是必需的