Java程序设计 多线程【三】

61 阅读2分钟

这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

Java程序设计 多线程【三】

同步与死锁

同步

线程同步是指若干个线程对象并行进行资源访问时实现的资源处理的保护操作

演示:卖货

未同步情况:

package org.test;
class Test implements Runnable{
    private int h = 5;
    @Override
    public void run() {
        while (true){
            if(this.h>0){
                try{
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                this.h=this.h-1;
                System.out.println(Thread.currentThread().getName()+"卖出一件,剩余"+this.h+"件");
            }else {
                System.out.println("没货了");
                break;
            }
        }
    }
}
public class Hello {
    public static void main(String[] args) throws Exception{
        Test t=new Test();
        new Thread(t,"A").start();
        new Thread(t,"B").start();
        new Thread(t,"C").start();
    }
}

image-20220124163831222

实现同步处理

Java中提供有synchronized关键字以实现同步处理,同步的关键是要为代码加上“锁”,而对于锁的操作程序有两种:同步代码块、同步方法。

同步代码块

package org.test;
class Test implements Runnable{
    private int h = 5;
    @Override
    public void run() {
        while (true){
            synchronized (this){
                if(this.h>0){
                    try{
                        Thread.sleep(100);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    this.h=this.h-1;
                    System.out.println(Thread.currentThread().getName()+"卖出一件,剩余"+this.h+"件");
                }else {
                    System.out.println("没货了");
                    break;
                }
            }
        }
    }
}
public class Hello {
    public static void main(String[] args) throws Exception{
        Test t=new Test();
        new Thread(t,"A").start();
        new Thread(t,"B").start();
        new Thread(t,"C").start();
    }
}

image-20220124164415483

当进行多个线程并发执行时,只允许有一个线程执行此部分代码,就实现了同步处理操作

同步方法

同步代码块可以直接定义在某个方法中,使得方法的部分操作进行同步处理,但是如果现在某一个方法中的全部操作都需要进行同步处理,则可以采用同步方法的形式进行定义,即在方法声明上使用synchronized关键字即可

package org.test;
class Test implements Runnable{
    private int h = 5;
    @Override
    public void run() {
        while (this.s()) {
            ;
        }
    }
    public synchronized boolean s() {
        if (this.h > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.h = this.h - 1;
            System.out.println(Thread.currentThread().getName() + "卖出一件,剩余" + this.h + "件");
            return true;
        } else {
            System.out.println("没货了");
            return false;
        }
    }
}
public class Hello {
    public static void main(String[] args) throws Exception{
        Test t=new Test();
        new Thread(t,"A").start();
        new Thread(t,"B").start();
        new Thread(t,"C").start();
    }
}

image-20220124170241173

死锁

死锁指两个线程都在等待对方先完成,造成了程序的停滞状态

class A{
    public synchronized void t(B b){
        System.out.println("你给我a 我就给你b");
        b.get();
    }
    public synchronized void get(){
        System.out.println("已获取");
    }
}
class B{
    public synchronized void t(A a){
        System.out.println("你给我b 我就给你a");
        a.get();
    }
    public synchronized void get(){
        System.out.println("已获取");
    }
}
public class Hello implements Runnable{
    private A a =new A();
    private B b =new B();
    public void DeadLock(){
        new Thread(this).start();
        a.t(b);
    }

    @Override
    public void run() {
        b.t(a);
    }

    public static void main(String[] args) {
        new Hello().DeadLock();
    }
}

image-20220124173208352

死锁一旦出现程序将进入等待状态并且不会向下继续执行