java基础之线程通信和死锁

目录

一:死锁

1:概念

2:产生死锁原因

3:例子

二:线程通信

1:概念

2:线程间通信的代码改进

3:等待唤醒机制

4:例子


一:死锁

1:概念

是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象。

2:产生死锁原因

同步弊端

效率低

如果出现了同步嵌套,就容易产生死锁问题

3:例子

如果完成一件事情需要两个工具,两个人同时工作当两个人同时拥有一个工具然后找另一个工具,由工具都在对方手中会找不到就会一直等待有工具资源,就会出现死锁。

二:线程通信

1:概念

针对同一个资源的操作有不同种类的线程

线程有生产者和消费者这样的问题称之为通信问题

2:线程间通信的代码改进

A:通过等待唤醒机制实现数据依次出现(等待唤醒方法在object类中)

B:把同步代码块改进为同步方法实现

3:等待唤醒机制

如何添加等待唤醒机制呢?

Object类中有三个方法:

void wait() 导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。

void notify() 唤醒正在等待对象监视器的单个线程。

void notifyAll() 唤醒正在等待对象监视器的所有线程。

4:例子

学生设置名字和取名字

分析:设置名字是生产者,取名字是消费者,取名字要在设置名字之后,或者说应该设置好名字以后再取名字。

package day33;

public class Student {
     int age;
     String name;
     boolean f;

    public Student() {
    }

    public Student(int age, String name) {

        this.age = age;
        this.name = name;
    }


    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
package day33;
/*创建GetName实现Runnable接口将学生对象当作参数传入*/
public class SetName implements Runnable{
    private  Student s;
    int x=0;
    public SetName(Student s){
        this.s=s;

    }

    @Override
    public void run() {
        while (true) {
            synchronized (s) {
                //当有值时等待,没有值时去赋值奇数次赋值李焕偶数次赋值丽华
                if(s.f){
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                if (x % 2 == 0) {
                    s.age = 18;
                    s.name = "李焕";
                } else {
                    s.age = 17;
                    s.name = "丽华";
                }
                x++;
                s.notify();
                s.f=true;


            }


        }
    }
}

package day33;
/*创建GetName实现Runnable接口将学生对象当作参数传入*/

public class GetName implements  Runnable{
    private  Student s;
    public GetName(Student s){
        this.s=s;

    }
    @Override
    public void run() {
        while (true){ synchronized (s){
            //当没有值时等待否则进入取值值时进入取值
            if(!s.f){
                try {
                    s.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println(s.name+"**"+s.age);
            s.notify();
            s.f=false;
        }
        }
    }}


package day33;

public class Test {
    public static void main(String[] args) {
        //创建线程对象将学生对象传入
        Student student = new Student();
        GetName getName = new GetName(student);
        SetName setName = new SetName(student);
        Thread pro = new Thread(setName);
        Thread cus = new Thread(getName);
        //启动线程
        cus.start();
        pro.start();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_50691399/article/details/121198423