多线程同步

一、同步代码块

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 @ 2022-04-24 12:05  panther125  阅读(56)  评论(0)    收藏  举报