多个线程多个锁2

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * BlockingQueue:顾名思义,首先它是一个队列,并且支持阻塞的机制,阻塞的放入和得到数据。
 * 我们要实现LinkedBlockingQueue下面两个简单的方法put和take。
 * put(anobject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的
 * 线程被阻断,直到BlockingQueue里面有空间再继续。
 * take:取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到
 * BlockingQueue有新的数据被加入。
 */
public class MyQueue {

    //1. 需要一个承装元素的集合
    private LinkedList<Object> list = new LinkedList<Object>();

    //2.需要一个计数器
    private AtomicInteger count = new AtomicInteger(0);

    //3.需要制定上限和下限
    private final int minSize = 0;
    private final int maxSize;

    //4. 构造方法
    public MyQueue(int size){
        this.maxSize = size;
    }

    //5. 初始化一个对象用于加锁
    private final Object lock = new Object();

    //put(anObject): 把anObject放到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续
    public void put(Object obj){
        synchronized (lock){
            while(count.get() == this.maxSize){
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            // 1 加入元素
            list.add(obj);
            // 2 计数器增加
            count.incrementAndGet();
            // 3 通知另外一个线程(唤醒)
            lock.notify();
            System.out.println("新加入的元素为:" + obj);
        }
    }

    //take: 取走BlockingQueue里排在首位的对象,若BolckingQueue为空,阻断进入等待状态
    //直到BlockingQueue有新的数据被加入
    public Object take(){
        Object ret = null;
        synchronized (lock){
            while(count.get() == this.minSize){
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //1 做移除元素操作
            ret = list.removeFirst();
            //2 计数器递减
            count.decrementAndGet();
            //3 唤醒另外一个线程
            lock.notify();
        }
        return ret;
    }

    public int getSize(){
        return this.count.get();
    }

    public static void main(String[] args) {
        final MyQueue mq = new MyQueue(5);
        mq.put("a");
        mq.put("b");
        mq.put("c");
        mq.put("d");
        mq.put("e");
        System.out.println("当前容器的长度:" + mq.getSize());

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                mq.put("f");
                mq.put("g");
            }
        },"t1");

        t1.start();

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                Object o1 = mq.take();
                System.out.println("移除的元素为:" + o1);
                Object o2 = mq.take();
                System.out.println("移除的元素为:" + o2);
            }
        },"t2");

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t2.start();
    }


    /**
     * 新加入的元素为:a
     * 新加入的元素为:b
     * 新加入的元素为:c
     * 新加入的元素为:d
     * 新加入的元素为:e
     * 当前容器的长度:5
     * 新加入的元素为:f
     * 移除的元素为:a
     * 移除的元素为:b
     * 新加入的元素为:g
     *
     * 解析: 可能打印顺序不对
     */


}

public class ChangeLock {

    private String lock = "lock";

    private void method(){
        synchronized (lock){
            try {
                System.out.println("当前线程:" + Thread.currentThread().getName() + "开始");
                lock = "change lock";
                Thread.sleep(2000);
                System.out.println("当前线程:" + Thread.currentThread().getName() + "结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        final ChangeLock changeLock = new ChangeLock();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                changeLock.method();
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                changeLock.method();
            }
        },"t2");

        t1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
    }

    /**
     * 执行结果:
     * 当前线程:t1开始
     * 当前线程:t2开始
     * 当前线程:t1结束
     * 当前线程:t2结束
     */
}
 
 
public class DeadLock implements Runnable {

    private String tag;

    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    public void setTag(String tag){
        this.tag = tag;
    }


    public void run() {
        if(tag.equals("a")){
            synchronized (lock1){
                try {
                    System.out.println("当前线程:"  + Thread.currentThread().getName() + "进入lock1执行");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2){
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "进入lock2执行");
                }
            }
        }

        if(tag.equals("b")){
            synchronized (lock2){
                try {
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "进入lock2执行");
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1){
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "进入lock1执行");
                }
            }
        }
    }

    public static void main(String[] args) {
        DeadLock d1 = new DeadLock();
        d1.setTag("a");
        DeadLock d2 = new DeadLock();
        d2.setTag("b");

        Thread t1 = new Thread(d1,"t1");
        Thread t2 = new Thread(d2,"t2");
        t1.start();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
    }

    /**
     * 两线程相互虚弱对方造成死锁
     */
}
 
 
/**
 * 同一对象属性的修改不会影响锁的情况
 */
public class ModifyLock {


    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public synchronized void changeAttribute(String name,int age){
        try {
            System.out.println("当前线程:" + Thread.currentThread().getName() + "开始");
            this.setName(name);
            this.setAge(age);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "修改对象内容为:" + this.getName() + "," + this.getAge());
            Thread.sleep(2000);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "结束");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        final ModifyLock modifyLock = new ModifyLock();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                modifyLock.changeAttribute("张三",20);
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                modifyLock.changeAttribute("李四",21);
            }
        },"t2");
        t1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
    }

    /**
     * 当前线程:t1开始
     * 当前线程:t1修改对象内容为:张三,20
     * 当前线程:t1结束
     * 当前线程:t2开始
     * 当前线程:t2修改对象内容为:李四,21
     * 当前线程:t2结束
     */
}
/**
 * 使用synchronized代码块加锁,比较灵活
 */
public class ObjectLock {

    public void method1(){
        synchronized (this){     //对象锁
            try {
                System.out.println("do method1..");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void method2(){
        synchronized (ObjectLock.class){ //类锁
            try {
                System.out.println("do method2..");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private Object lock = new Object();
    public void method3(){  //任何对象锁
        synchronized (lock){
            try {
                System.out.println("do method3..");
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        final ObjectLock objLock = new ObjectLock();
        Thread t1 = new Thread(new Runnable(){
            public void run() {
                objLock.method1();
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                objLock.method2();
            }
        });
        
        Thread t3 = new Thread(new Runnable() {
            public void run() {
                objLock.method3();
            }
        });
        t1.start();
        t2.start();
        t3.start();
    }
}
/**
 * 使用synchronized代码块减小锁的粒度,提高性能
 */
public class Optimize {

    public void doLongTimeTask(){
        try {
            System.out.println("当前线程开始:" + Thread.currentThread().getName() +
                    ",正在执行一个较长时间的业务操作,其内容不需要同步");
            Thread.sleep(2000);
            synchronized (this){
                System.out.println("当前线程:" + Thread.currentThread().getName() +
                        ",执行同步代码块,对其同步变量进行操作");
                Thread.sleep(1000);
            }
            System.out.println("当前线程结束:" + Thread.currentThread().getName() +
                    ",执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        final Optimize otz = new Optimize();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                otz.doLongTimeTask();
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                otz.doLongTimeTask();
            }
        },"t2");
        t1.start();
        t2.start();
    }

    /**
     * 执行结果:
     * 当前线程开始:t1,正在执行一个较长时间的业务操作,其内容不需要同步
     * 当前线程开始:t2,正在执行一个较长时间的业务操作,其内容不需要同步
     * 当前线程:t1,执行同步代码块,对其同步变量进行操作
     * 当前线程结束:t1,执行完毕
     * 当前线程:t2,执行同步代码块,对其同步变量进行操作
     * 当前线程结束:t2,执行完毕
     */
}
/**
 * synchronized 代码块对字符串的锁,注意String常量池的缓存功能
 */
public class StringLock {

    public void method(){
        synchronized (new String("字符串常量")){
            try {
                while(true){
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "开始");
                    Thread.sleep(1000);
                    System.out.println("当前线程:" + Thread.currentThread().getName() + "结束");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        final StringLock stringLock = new StringLock();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                stringLock.method();
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                stringLock.method();
            }
        },"t2");
        t1.start();
        t2.start();
    }

    /**
     * new String new出两个对象
     */

}
/**
 * ThreadLocal概念:线程局部变量,是一种多线程间并发访问变量的解决方案。
 * 与其synchronized等加锁的方式不同,ThreadLocal完全不提供锁,而使用以
 * 空间换时间的手段,为每个线程提供变量的独立副本,以保证线程安全。
 * 
 * 从性能上说,ThreadLocal不具有绝对的优势,在并发不是很高的时候,加锁的性能会更好,
 * 但作为一套与锁完全无关的线程安全解决方案,在高并发量或者竞争激烈的场景,使用
 * ThreadLocal可以在一定程度上减少锁竞争。
 */
public class ConnThreadLocal {

    /**
     * 当前这个线程设置这个变量跟另外一个线程他们俩是不可见的
     */
    public static ThreadLocal<String> th = new ThreadLocal<String>();

    public void setTh(String value){
        th.set(value);
    }

    public void getTh(){
        System.out.println(Thread.currentThread().getName() + ":" + this.th.get());
    }

    public static void main(String[] args) {
        final ConnThreadLocal ct = new ConnThreadLocal();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                ct.setTh("张三");
                ct.getTh();
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                try {
                    Thread.sleep(1000);
                    ct.getTh();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"t2");

        t1.start();
        t2.start();
    }
    /**
     * 征对这个线程内是有效的
     * t1:张三
     * t2:null
     */
}
/**
 * 单例模式,最常见的就是饥饿模式,和懒汉模式,一个直接实例化对象,一个在调用方法时
 * 进行实例化对象。在多线程模式中,考虑到性能和线程安全问题,我们一般选择下面两种比较
 * 经典的单例模式,在性能提高的同时,又保证了线程安全。
 * dubble check instance
 * static inner class
 */
public class DubbleSingleton {

    private static DubbleSingleton ds;

    public static DubbleSingleton getDs(){
        if(ds == null){
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (DubbleSingleton.class){
                if(ds == null){
                    ds = new DubbleSingleton();
                }
            }
        }
        return ds;
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t2");

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                System.out.println(DubbleSingleton.getDs().hashCode());
            }
        },"t3");

        t1.start();
        t2.start();
        t3.start();
    }
}
public class Singletion {
    
    private static class InnerSingletion{
        private static Singletion singletion = new Singletion();
    }
    
    public static Singletion getInstance(){
        return InnerSingletion.singletion;
    }
}

 

猜你喜欢

转载自blog.csdn.net/jz1993/article/details/80714013