Lock接口

Synchronized

实例:三个售票员销售三十张票

package com.yyp.demo02;

//创建资源类
class Ticket{
    private int number = 300;
    public synchronized void sale(){
        if (number>0){
            System.out.println(Thread.currentThread().getName()+":卖出了:"
            +(number--)+":剩余:"+number);
        }
    }
}

public class SaleTicket {
    //第二步创建多个线程,调用资源类操作方法
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<400;i++){
                    ticket.sale();
                }
            }
        },"AA").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<400;i++){
                    ticket.sale();
                }
            }
        },"BB").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<400;i++){
                    ticket.sale();
                }
            }
        },"CC").start();
    }
}

Lock接口

可重入锁
还是卖票的的实例:

package com.yyp.demo02;

import java.util.concurrent.locks.ReentrantLock;

class LTicket{

    private int number=3000;

    //创建可重入锁
    private final ReentrantLock lock=new ReentrantLock();

    public void sale(){
        lock.lock();
        try {
            if (number>0){
                System.out.println(Thread.currentThread().getName()+":卖出了:"
                +(number--)+":剩余:"+number);
            }
        } finally {
            lock.unlock();
        }
    }
}

public class LSaleTicket {
    public static void main(String[] args) {
        LTicket ticket = new LTicket();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<1000;i++){
                    ticket.sale();
                }
            }
        },"AA").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<1000;i++){
                    ticket.sale();
                }
            }
        },"BB").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0;i<1000;i++){
                    ticket.sale();
                }
            }
        },"CC").start();
    }
}

Synchronized和Lock的区别

  • Lock是一个接口,而synchronized是Java中的关键字,synchronized是内
    置的语言实现;
  • synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现
    象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;·
  • Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;
  • 通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。
  • Lock可以提高多个线程进行读操作的效率

带通知的实例

有两个线程,实现对一个初始值是0的变量进行操作,一个线程+1,一个线程-1

Synchronized实现

package com.yyp.demo03;

class Share{
    private int number=0;
    public synchronized void incr() throws InterruptedException {
        if (number!=0){
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName()+"::"+number);
        this.notifyAll();
    }
    public synchronized void decr() throws InterruptedException {
        if (number!=1){
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName()+"::"+number);
        this.notifyAll();
    }
}

public class TreadDemo1 {
    public static void main(String[] args) {
        Share share = new Share();
        new Thread(()->{
            for (int i= 1;i<=10;i++){
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i= 1;i<=10;i++){
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
}

可能会有虚假唤醒的情况,我们要防止虚假唤醒的情况。
Lock实现

package com.yyp.demo03;

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

class LShare{
    private int number=0;
    private Lock lock=new ReentrantLock();
    private Condition condition = lock.newCondition();
    public void incr() throws InterruptedException {
        lock.lock();
        try {
            while (number!=0){
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName()+"::"+number);
            condition.signalAll();
        }finally {
            lock.unlock();
        }
    }
    public void decr() throws InterruptedException {
        lock.lock();
        try {
            while (number!=1){
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName()+"::"+number);
            condition.signalAll();
        }finally {
            lock.unlock();
        }
    }
}

public class Treaddemo2 {
    public static void main(String[] args) {
        LShare share = new LShare();
        new Thread(()->{
            for (int i= 1;i<=10;i++){
                try {
                    share.incr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"A").start();
        new Thread(()->{
            for (int i= 1;i<=10;i++){
                try {
                    share.decr();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"B").start();
    }
}

线程间定制化通信

要求,启动三个线程,
AA打印五次,BB打印十次,CC打印十五次,执行10轮

package com.yyp.demo04;

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

class ShareResource{
    private int flag = 1;
    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    public  void  print5(int loop) throws InterruptedException {
        lock.lock();
        try{
            while (flag !=1){
                c1.await();
            }
            for (int i=1;i<=5;i++){
                System.out.println(Thread.currentThread().getName()+"::"+i+":轮数:"+loop);
                flag = 2;
                c2.signal();
            }
        }finally {
            lock.unlock();
        }
    }
    public  void  print10(int loop) throws InterruptedException {
        lock.lock();
        try{
            while (flag !=2){
                c1.await();
            }
            for (int i=1;i<=10;i++){
                System.out.println(Thread.currentThread().getName()+"::"+i+":轮数:"+loop);
                flag = 3;
                c3.signal();
            }
        }finally {
            lock.unlock();
        }
    }
    public  void  print15(int loop) throws InterruptedException {
        lock.lock();
        try{
            while (flag !=3){
                c3.await();
            }
            for (int i=1;i<=15;i++){
                System.out.println(Thread.currentThread().getName()+"::"+i+":轮数:"+loop);
                flag = 1;
                c1.signal();
            }
        }finally {
            lock.unlock();
        }
    }
}

public class ThreadDemo03 {
    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    shareResource.print5(i+1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    shareResource.print10(i+1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();
        new Thread(()->{
            for (int i=0;i<10;i++){
                try {
                    shareResource.print15(i+1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"CC").start();
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值