synchronized、lock及线程安全集合

synchronized调用及写法说明:

主调用:

    public static void synchronizedTest(){
        //此处注意:3个线程传入的同一个对象,才能共享同一个资源
        MyRunnableLock myRunnableLock=new MyRunnableLock();

        Thread th1=new Thread(myRunnableLock,"线程1");
        Thread th2=new Thread(myRunnableLock,"线程2");
        Thread th3=new Thread(myRunnableLock,"线程3");

        //静态方法的测试,不同对象也可以锁
//        Thread th1=new Thread(new MyRunnableLock(),"线程1");
//        Thread th2=new Thread(new MyRunnableLock(),"线程2");
//        Thread th3=new Thread(new MyRunnableLock(),"线程3");

        th1.start();
        th2.start();
        th3.start();
    }

调用类:

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

/*
*Linux中,一个进程一个独立空间,包括:代码区、堆内存地址
* 进程下的所有线程共享进程的独立空间。
*
*
* 加锁3个条件:
* 1.是否是多线程环境
* 2.是否有共享数据
* 3.是否有多条语句操作共享数据
*
* 本质:锁对共享资源的控制就可以
* */
public class MyRunnableLock implements Runnable {
    private int num=100;
    private int num1=100;
    private static int num2=100;

    private Object o =new Object();

    //Lock为接口,实现类ReentrantLock
    Lock lock=new ReentrantLock();


    @Override
    public void run() {
        while (true){

            exectue1();

            exectue2();

            exectue3();

            exectue4();
        }
    }

    /*
     * 第一种方式:锁一个对象,此对象必须共享
     * */
    private void exectue1() {
        synchronized (o){
            if (num>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+num);
                num--;
            }
        }
    }

    /*
    * 方式二:
    * 这种写法锁的是当前对象实例 this,所以必须为同一个对象
    * */
    public synchronized void exectue2(){
        if (num1>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+num1);
            num1--;
        }
    }

    /*
    * 方式三:
    * 此静态方法,锁的是当前类 MyRunnableLock.Class
    * 所有只有是new的该类,都暂用同一个锁
    * */
    public static synchronized void exectue3(){
        if (num2>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":"+num2);
            num2--;
        }
    }

}

Lock:

    /*
    * 方式四:Lock
    * lock必须为同一个锁对象
    * */
    private void exectue4() {
        try {
            //开启锁
            lock.lock();

            if (num>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+":"+num);
                num--;
            }
        }finally {
            //释放锁
            lock.unlock();
        }
    }

 

线程安全集合:

    /*
    * 线程安全集合
    * */
    private void getSynchronizedList(){
        /*
        * Collections集合:
        * Vector:java封装的线程安全的
        * Collections.synchronizedList:用法比较多,将一个普通集合封装为线程安全机会,内部调用做加锁控制
        * */
        Vector<String> vector=new Vector<>();
        List<String> strings = Collections.synchronizedList(new ArrayList<String>());

        /*
        * Map集合:
        * Hashtable:java封装的线程安全的字典集合
        * Collections.synchronizedMapt:用法比较多,将一个普通集合封装为线程安全机会,内部调用做加锁控制
        * */
        Hashtable<Integer,String> hashtable=new Hashtable<>();
        Map<Integer, String> integerStringMap = Collections.synchronizedMap(new HashMap<Integer, String>());

        /*
        * StringBuffer:java封装的线程安全字符串拼接
        * StringBuilder:线程不安全
        * */
        StringBuffer sb=new StringBuffer();
        StringBuilder sb1=new StringBuilder();
    }

 

posted @ 2020-10-16 11:15  zhuyapeng  阅读(170)  评论(0编辑  收藏  举报