多线程同步

一、同步代码块

lock是一个锁对象,它是同步代码块的的关键

复制代码
class myThread2 implements Runnable{
    private int tickets =10;
    private final Object lock = new Object();//任意对象类型
    @Override
    public void run() {
        while(true){
            synchronized(lock){
                if(tickets >0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在售出"+tickets--+"张票");
                }
            }
        }
    }
}


public class synchronizeddemo {

    public static void main(String[] args) {
        myThread2 run = new myThread2();
        Thread t1 = new Thread(run,"t1线程");
        Thread t2 = new Thread(run,"t2线程");
        Thread t3 = new Thread(run,"t3线程");
        t1.start();
        t2.start();
        t3.start();
}
复制代码

注意:锁对象不能放到run方法中,否则每个线程运行到run方法是都会创建一个新对象,每个线程都会有一个不同的锁,便不会产生同步效果

二、同步方法

被synchronized修饰的方法在某一时刻只允许一个线程访问,其他线程会发生阻塞,只有当前线程访问结束,其他线程才有机会访问

复制代码
private int tickets = 10;
    private final Object lock = new Object();//任意对象类型

    @Override
    public void run() {
        while(true) {
            saleTicket();
        }
    }
    private synchronized void saleTicket(){

            synchronized(lock){
                if(tickets >0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在售出"+tickets--+"张票");
                }
        }
    }
复制代码

同步方法也有锁,它的锁就是当前调用该方法的对象,也就是this指向的对象。

静态方法也有锁,它的锁是该方法所在类的class对象,可以使用类名.class获取

同步代码锁有好处也有弊端,同步锁解决了多个线程同时访问共享数据时的线程安全问题,加上锁在同一时间只能有一条线程执行,但线程在执行时每次都需要判断锁的状态,每次消耗资源,效率较低

三、同步锁

从JDK5开始JAVA增加了功能强大的Lock锁Lock锁于synchronized隐式锁功能相同,优势在于Lock锁可以让某个线程在持续获取同步锁失败后返回

 

复制代码
private final Lock lock = new ReentrantLock();//ReentrantLock是Lock的实现类,也是常用的同步锁
    @Override
    public void run() {
        while(true) {
            lock.lock();//加锁
                if(tickets >0){
                    try {
                        Thread.sleep(100);
                        System.out.println(Thread.currentThread().getName()+"正在售出"+tickets--+"张票");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                    lock.unlock();//解锁
                }
            }
        }
    }                                                                                                                                                                                                                       
复制代码

 

四、死锁问题

两个线程在运行时都在等待对方的锁,这便造成死锁

复制代码
class DeadLock implements Runnable{
    private boolean flag;
    //定义两个锁
    static Object lock1 = new Object();
    static Object lock2 = new Object();
    DeadLock(boolean flag){
        this.flag =flag;
    }
    @Override
    public void run() {
        //判断线程的入口
        if(flag){
            while(true){
                synchronized(lock1){
                    System.out.println(Thread.currentThread().getName()+"is runing");
                    synchronized (lock2){
                        System.out.println(Thread.currentThread().getName()+"is running");
                    }
                }
            }
        }else{
            while(true){
                synchronized(lock2){
                    System.out.println(Thread.currentThread().getName()+"is runing");
                    synchronized (lock1){
                        System.out.println(Thread.currentThread().getName()+"is running");
                    }
                }
        }

    }
}

}
public  class deadlock {
    public static void main(String[] args) {
        //创建Deadlock对象
        DeadLock t1 = new DeadLock(true);
        DeadLock t2 = new DeadLock(false);
        new Thread(t1,"Thread-1").start();
        new Thread(t2,"Thread-2").start();
    }
}
复制代码

在上述代码中,两个线程都需要对方的锁,单都无法释放当前的锁,导致程序处于挂起状态

posted @   panther125  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示