Synchronized thread lock



1. multithreading possible security problems

public class Synchronizedtest implements Runnable {

    int i = 10;     //共享变量

    @Override
    public void run() {
        if( i == 10 ){
            System.out.println("i == 10");
            sys
            i++;
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        
        Synchronizedtest st = new Synchronizedtest();
        Thread t1 = new Thread(st,"线程1");
        Thread t2 = new Thread(st,"线程2");
        
        t1.start();
        // t1.sleep(1000);  第一次测试先注释掉,第二次测试打开,下面为两次测试结果
        t2.start();
    }
}
i == 10
i == 10
i == 10


problem analysis:

  • i ++ The operation of non-atoms, is divided into three steps:
    • Reading the value of i
    • The read value +
    • The value written back i
  • Before the thread t1, read the value of i is 10, in the write-back value i (i ++ = 11), t2 thread reads the value of i, at this time t1 the value of i is not modified, so that i is equal to 10
  • I is therefore determined both equal to 10, i.e., the content will be output
  • Perform a second test t1.start () to " 暂停" 1 sec, t2 is not open thread, the thread t2 after t1 before opening absolutely be executed within one second, it has been updated so that the value of i is 11, and at this time t2 is not outputting content
  • If you do not put the variable on the member variable, but on the inside the method, so you do not share, because the method is to stack operations, exclusive space




2. Solution

  • Shared variable is not set, be placed in the stack vivo exclusive space

  • With final modifications underlying variables, but with a final reference variables modified or not (pointing immutable, but the content of the variable)

  • Lock (Built-in lock, display Lock lock), there will be explained later

  • Use safety class

    • Atomicity: Atomic packet

    • Container: ConcurrentHashMap

    • locks package




3. Prepare the knowledge and keywords

  • Atomicity: performing a plurality of operations, one operation which is not implemented, the entire operation is not executed; otherwise, all performed
  • Memory barrier: CPU has a cache, if the data in the cache, and memory can not happen in real-time exchange of information, the CPU executes different points in different threads on different values ​​for the same variable cache
  • Ordering: performing sequential code according to the execution code sequence, without considering the reordering (before the JVM instruction is executed and optimization reordering)
  • Visibility: modify a shared variable thread, another thread can see immediately
    • volatile : lightweight synchronization mechanism, only the modified class and instance variables, only to ensure the visibility, does not guarantee atomicity, to ensure orderly , after a variable is modified all know that the process variable is modified, but if the re-assignment, this is not atomic three-step (Once the write operation is completed, the process will get all the latest value)




4 Lock


4.1 synchronized built-in lock

  • It is java keywords, the method may be modified, block, class
  • synchronized lock can only allow one thread to enter the locked block of code, java each object has built-in lock / monitor lock, is synchronized using the built-in lock to lock the object of the
  • Atoms and visibility within the lock guarantees


4.1.1 Method lock

public class Synchronizedtest implements Runnable {
    
    //使用的是该类的锁
    @Override
    public synchronized void run() {
        for(int i = 0;i < 100;i++){
            System.out.println(Thread.currentThread().getName() + "------" + i);
        }
    }
    
    public static void main(String[] args) {
        
        Synchronizedtest st = new Synchronizedtest();
        Thread t1 = new Thread(st,"线程1");
        Thread t2 = new Thread(st,"线程2");
        
        t1.start();
        t2.start();
    }
}
线程1------96
线程1------97
线程1------98
线程1------99    //获得锁,执行完才释放,t2线程不能执行该方法
线程2------0
线程2------1
线程2------2
线程2------3
线程2------4


4.1.2 Lock block

public void run() {

    //使用的也是该类的锁,打印结果是一致的
    //也可以用一个对象作为锁,客户端锁,但不推荐
    synchronized(this){
        for(int i = 0;i < 100;i++){
            System.out.println(Thread.currentThread().getName() + "------" + i);
        }
    }
}


4.1.3 Static lock

public class test {

    //静态方法属于类,获取到的锁是属于类锁(类的字节码文件对象)
    public static synchronized void test() {
    }
}


4.1.4 Class and Object Lock Lock

The two do not conflict, that is, you can get the object lock, the lock is also available Class

public class testLock {

    //对象锁
    public synchronized void lockOne() throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }
    
    //类锁
    public static synchronized void lockTwo() throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
    }

    public static void main(String[] args) {
        testLock demo = new testLock();

       
        Thread t1 = new Thread(() -> {
            try {
                demo.lockOne();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });
        Thread t2 = new Thread(() -> {
            try {
                lockTwo();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });
        
        t1.start();
        t2.start();
    }
}
//两个线程都执行
Thread-1: 99
Thread-0: 35


4.1.5 lock built reentrancy

public class Widget {

    // 锁住了
    public synchronized void doSomething() {
        System.out.println("Wigget--------------");
    }
}

public class LoggingWidget extends Widget {

    // 锁住了
    public synchronized void doSomething() {
        System.out.println("LoggingWidget------------");
        super.doSomething();
    }
}
  • You can run without deadlock
  • Thread running LoggingWidget of dosomething () method to obtain LoggingWidget object instance lock
  • When calling super.doSomething (); when the caller or LoggingWidget, acquired LoggingWidget object instances again lock, the lock again, i.e. re-entry lock
  • The above lock is in the instance of the object, not on the type of lock is the same, but not to obtain a multi-lock (lock each have a counter and associated objects, when a thread requests the lock successful, the JVM a note the thread holding the lock, and the counter is set to 1; another thread requests the lock case, you must wait; the same thread if the lock request again, you can get the lock again, while the counter is incremented; when the thread exit sync block, the counter is decremented, if the counter is 0, the lock is released)

Guess you like

Origin www.cnblogs.com/Howlet/p/12230652.html