05月18, 2017

Java多线程synchronized关键字

synchronized关键字代表着同步的意思,在Java中被synchronized修饰的有三种情况

1.同步代码块

//锁为obj
synchronized(obj){
    while(true){
        if(product > 0){
            System.out.println(Thread.currentThread().getName()+"消费:"+product--);
        }
    }
}

2.同步函数

//锁为this
public synchronized void  consume() {
        while(true){
            if(product > 0){
                System.out.println(Thread.currentThread().getName()+"消费:"+product--);
            }
        }
}

  

3.静态同步函数

//锁为this.getClass()
static public synchronized void  consume() {
        while(true){
            if(product > 0){
                System.out.println(Thread.currentThread().getName()+"消费:"+product--);
            }
        }
}

死锁案例

1.同步嵌套

package threaddemo;

public class DeathLock {
    public static void main(String[] args) {
        Callable c1 = new Callable(true);
        Callable c2 = new Callable(false);

        Thread t1 = new Thread(c1);
        Thread t2 = new Thread(c2);

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

class MyLock {
    static final public Object locka = new Object();
    static final public Object lockb = new Object();
}

class Callable implements Runnable {
    private boolean flag;

    public Callable(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        String name  = Thread.currentThread().getName();
        if (flag) {
            synchronized (MyLock.locka) {
                System.out.println(name+":获取到了locka");
                synchronized (MyLock.lockb) {
                    System.out.println(name+":获取到了lockb");
                }
                System.out.println(name+":释放了lockb");
            }
            System.out.println(name+":释放了locka");

        } else {
            synchronized (MyLock.lockb) {
                System.out.println(name+":获取到了lockb");
                synchronized (MyLock.locka) {
                    System.out.println(name+":获取到了locka");
                }
                System.out.println(name+":释放了locka");
            }
            System.out.println(name+":释放了lockb");
        }
    }
}

2.多生产者多消费者时只使用notify(),线程通讯死锁

解决办法采用notifyAll代替notify,唤醒所有线程就不会导致死锁

package threaddemo;

/**
 * 多生产者消费者线程通讯死锁
 * @author wpy
 *
 */
public class ProducerConsumerDeathLock {
    public static void main(String[] args) {
        Resource resource = new Resource();

        Producer producer0 = new Producer(resource);
        Producer producer1 = new Producer(resource);

        Consumer consumer2 = new Consumer(resource);
        Consumer consumer3 = new Consumer(resource);

        Thread t0 = new Thread(producer0);
        Thread t1 = new Thread(producer1);
        Thread t2 = new Thread(consumer2);
        Thread t3 = new Thread(consumer3);

        t0.start();
        t1.start();

        t2.start();
        t3.start();

    }

}

class Producer implements Runnable {
    private Resource resource;

    public Producer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            resource.set("资源");
        }
    }
}

class Consumer implements Runnable {
    private Resource resource;

    public Consumer(Resource resource) {
        this.resource = resource;
    }

    @Override
    public void run() {
        while (true) {
            resource.out();
        }
    }
}

class Resource {
    private String name;
    private int count = 1;
    // 是否生成完毕
    private boolean flag = false;

    public synchronized void set(String name) {
        String threadName = Thread.currentThread().getName();
        while (flag) {
            try {
                System.out.println(threadName+"进入等待状态");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(threadName+"取得执行权");

        this.name = name + count;
        count++;
        System.out.println("生产者:" + this.name);
        flag = true;
        this.notify();
//        this.notifyAll();
    }

    public synchronized void out() {
        String threadName = Thread.currentThread().getName();
        while (!flag) {
            try {
                System.out.println(threadName+"进入等待状态");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(threadName+"取得执行权");

        System.out.println("============消费者:" + name);
        flag = false;
        this.notify();
//        this.notifyAll();
    }
}

代码执行结果:

Thread-0取得执行权 生产者:资源1 Thread-0进入等待状态 Thread-1进入等待状态 Thread-3取得执行权 ============消费者:资源1 Thread-3进入等待状态 Thread-2进入等待状态 Thread-0取得执行权 生产者:资源2 Thread-0进入等待状态 Thread-1进入等待状态

  

本文链接:https://www.qiangshuidiyu.xin/post/2017-05-18.html

-- EOF --

Comments