Java线程线程的间隔打印

/*
* Person类 姓名 性别
* 开启两个线程
* 一个对Person对象进行赋值
* 一个对Person对象进行打印
* 要求
* 一次打印 丁鹏 男
* 一次打印 dingpeng nv
* 间隔输出
*
* 1.先保证要操作的是同一个对象
* 2.要保证数据安全需要使用锁,并且要使用同一把锁
* 3.保证操作的逻辑顺序要对(先赋值,在打印)用 wait 和 notify
*/
public class Demo06 {
public static void main(String[] args) {
// 创建对象(只能使用同一个对象)
Person person = new Person();

    // 创建线程
    SetRunnable setRunnable = new SetRunnable(person);
    Thread thread1 = new Thread(setRunnable);

    PrintRunnable printRunnable = new PrintRunnable(person);
    Thread thread2 = new Thread(printRunnable);

    thread1.start();
    thread2.start();
}

}
// 赋值线程
class SetRunnable implements Runnable {
// 利用成员变量,来操作同一个对象
private Person person;
// 定义一个标识通过改变标识来进行间隔赋值
private boolean isTrue = true;
// 利用构造方法来给成员变量赋值
public SetRunnable() {
super();
}
public SetRunnable(Person person) {
super();
this.person = person;
}

@Override
public void run() {
    while (true) {
        // 多个线程操作共享数据
        // 需要添加锁
        // 为了保证两个同步锁的锁对象相同,使用传进来的对象 person
        /*
         * 赋值线程需要赋值完毕,打印线程才能去打印
         * 赋值时,打印线程等待,赋值完毕后,通知打印线程,打印线程才能打印
         * 
         * 同样,打印线程打印完毕,赋值线程才能赋值
         * 打印时,赋值线程等待,打印完毕后,通知赋值线程,赋值线程才能赋值
         * 
         * wait 和 notify 使用一个标记来进行切换
         * 这个标记赋值线程使用,也要给打印线程使用
         * 注意:必须保证使用的是用一个标记,标记声明在 person 类中,即声明在共同对象中
         * 
         */
        synchronized (person) {
            // 判断 flag 为 true 时等待,不为 true 时赋值
            if (person.flag == true) {
                // 进行等待
                try {
                    person.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 间隔赋值
            if (isTrue) {
                person.name = "张三";
                person.gender = "男";
            } else {
                person.name = "zhangsan";
                person.gender = "nv";
            }
            // 改变标识符
            isTrue = !isTrue;
            // 修改标记
            person.flag = true;
            // 唤醒线程
            person.notify();
        }
    }
}

}
// 打印线程
class PrintRunnable implements Runnable {
// 利用成员变量,来操作同一个对象
private Person person;
public PrintRunnable() {
super();
}
public PrintRunnable(Person person) {
super();
this.person = person;
}

@Override
public void run() {
    while (true) {
        synchronized (person) {
            if (person.flag == false) {
                try {
                    person.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// 打印
System.out.println(person);
// 修改标记
person.flag = false;
// 唤醒线程
person.notify();
}
}
}
}
class Person {
public String name;
public String gender;
// 声明标记来切换打印和赋值
public boolean flag = false;
@Override
public String toString() {
return “姓名:” + name + “\n年龄:” + gender;
}

}

/*
* Person1类 姓名 性别
* 开启两个线程
* 一个对Person1对象进行赋值
* 一个对Person1对象进行打印
* 要求
* 一次打印 丁鹏 男
* 一次打印 dingpeng nv
* 间隔输出
*
* 1.先保证要操作的是同一个对象
* 2.要保证数据安全需要使用锁,并且要使用同一把锁
* 3.保证操作的逻辑顺序要对(先赋值,在打印)用 wait 和 notify
*/
public class Demo07 {
public static void main(String[] args) {
// 创建对象(只能使用同一个对象)
Person1 person1 = new Person1();

    // 创建线程
    SetRunnable1 setRunnable1 = new SetRunnable1(person1);
    Thread thread1 = new Thread(setRunnable1);

    PrintRunnable1 printRunnable1 = new PrintRunnable1(person1);
    Thread thread2 = new Thread(printRunnable1);

    thread1.start();
    thread2.start();
}

}
// 赋值线程
class SetRunnable1 implements Runnable {
// 利用成员变量,来操作同一个对象
private Person1 person1;
// 定义一个标识通过改变标识来进行间隔赋值
private boolean isTrue = true;
// 利用构造方法来给成员变量赋值
public SetRunnable1() {
super();
}
public SetRunnable1(Person1 person1) {
super();
this.person1 = person1;
}

@Override
public void run() {
    while (true) {
        /*
         * 代码优化
         * 把之前上锁的代码封装到类中
         * 从同步代码块封装成同步方法
         */
        if (isTrue) {
            person1.setPerson("张三", "男");
        } else {
            person1.setPerson("张珊", "女");
        }
        isTrue = !isTrue;
    }
}

}
// 打印线程
class PrintRunnable1 implements Runnable {
// 利用成员变量,来操作同一个对象
private Person1 person1;
public PrintRunnable1() {
super();
}
public PrintRunnable1(Person1 person1) {
super();
this.person1 = person1;
}

@Override
public void run() {
    while (true) {
        person1.print();
    }
}

}
class Person1 {
public String name;
public String gender;
// 声明标记来切换打印和赋值
public boolean flag = false;

// 把操作共享数据的部分写成一个同步的方法
public synchronized void setPerson(String name, String gender) {
    // 等待和唤醒
    if (flag == true) {
        try {
            this.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    this.name = name;
    this.gender = gender;
    // 更改标记
    flag = true;
    // 唤醒线程
    this.notify();
}
// 打印方法
public synchronized void print() {
    if (flag == false) {
        try {
            this.wait();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    System.out.println(name + " " + gender);
    flag = false;
    this.notify();
}

@Override
public String toString() {
    return "姓名:" + name + "\n年龄:" + gender;
}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值