多线程进阶 Synchroized锁 Lock锁复习

使用OOP思想写多线程

在入门学习多线程时一般是继承runable接口去执行

但是在真正的多线程开发中,线程是一个单独的资源没有额外的操作
多线程操作只需要我们吧资源类丢入线程即可(这样的写法能降低耦合性)

简单例子:

package com.jie.demo1;

public class SaleTicketDemo1 {
    public static void main(String[] args) {
        Ticket ticket=new Ticket();
        //lambda表达式 (参数)->{代码}
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket.sale();
            }
        },"小A").start();
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket.sale();
            }
        },"小B").start();
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket.sale();
            }
        },"小C").start();
    }
}
//资源类OOP
class Ticket{
    private Integer number;

    public Ticket() {
        this.number=50;
    }
    //模拟卖票
    public synchronized void sale(){
        if(number>0){
            System.out.println(Thread.currentThread().getName()+"卖出了"+(number--));
        }
    }
}

可以看到我们要操作的类与多线程并没有关系,只需要在多线程运行时吧类扔进去运行即可 做到了解耦

使用Lock锁

公平锁 必须先来后到
非公平锁 可以插队

package com.jie.demo1;

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

public class SaleTicketDemo2 {
    public static void main(String[] args) {
        Ticket2 ticket2=new Ticket2();
        //lambda表达式 (参数)->{代码}
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket2.sale();
            }
        },"小A").start();
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket2.sale();
            }
        },"小B").start();
        new Thread(()->{
            for(int i=0;i<30;i++){
                ticket2.sale();
            }
        },"小C").start();
    }
}
//资源类OOP
class Ticket2{
    private Integer number;
    //默认为非公平锁 如果构造时传一个true就是公平锁
    Lock lock=new ReentrantLock();
    public Ticket2() {
        this.number=50;
    }
    //模拟卖票
    public void sale(){
        lock.lock();//加锁
        try{
            if(number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(number--));
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }
        finally {
            lock.unlock();//解锁
        }
    }
}

两者区别


在lock里有方法lock.tryLock()会尝试获得锁 所以可以通过该方法使得线程不会一直等待

posted @ 2021-09-08 17:01  一个经常掉线的人  阅读(34)  评论(0)    收藏  举报