Demo15_死锁

package test06;

public class Demo15_死锁 {

public static void main(String[] args) {

// ticket1 t = new ticket1();
// Thread t1 = new Thread(t);
// Thread t2 = new Thread(t);
// t1.start();//开启时运行
// try{Thread.sleep(10);}catch(InterruptedException e){}
// t.flag = false ;
//
// t2.start();

//创建资源对象
    Resource r = new Resource();

// 创建线程任务
Producer pro = new Producer(r);
Consumer1 con = new Consumer1(r);
// 创建线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
t1.start();
t2.start();
}

}
/*
*同步的另一个弊端
*当线程任务中出现多个同步(多个锁)时,如果同步中嵌套着其他同步这时就容易发生死锁
*thread-0
*synchronized(obj1){synchronized(obj2){}}
*thread-1
*synchronized(obj2){synchronized(obj1){}}

class ticket1 implements Runnable
{
public boolean flag = true ;
//1.定义票的总数量
static int tickets = 10 ;
private Object obj = new Object();
//2.售票的动作,这个动作会被多线程执行,那就是线程任务代码,需要定义在run方法中
@Override
public void run() {
if(flag)
{
while(true)
{
synchronized (obj) {
sale();
}
}
//this.sale();
//静态函数没有this 随着对象的加载而加载
}

    else {
        while(true){
            this.sale();
        }
    }
}

public synchronized void sale()
{
    synchronized (obj) {
    if( tickets > 0 )
    {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
        }
        System.out.println(Thread.currentThread().getName()+"......"+tickets--);//得知那张票是谁卖出的线程名字从Thread_0开始
    }
    }
}

} */

/*多线程中较为常见的应用案例
*
*
*生产者消费者问题
*
*二者同时执行,执行任务不同,处理资源相同:线程间的通信
*
*生产者什么时候生产,消费者什么时候消费
*当盘里没有面包时候,生产,当盘子里有面包时消费
*
*生产这声场乐山品质后通知消费者来消费,这时候生产者处于等待状态。消费者消费完之后通知生产者生产,这时候消费者处于等待状态
*
*等待:wait();
*告诉:notify();//唤醒
*
*问题解决,实现生产一个消费一个
*
*=================================
*
*等待/唤醒机制
*wait();让线程处于等待状态,其实就是将线程临时存储于线程池中
*notify();会唤醒线程池中任意一个等待的线程
*notifyAll();会唤醒线程池中所有的等待的线程
*
*这些方法必须表示在同步中,因为必须标识wait,notify等方法所属的锁,同一个锁上的notify,只能唤醒该锁上被wait的线程
*
*为什么这些方法定义在object中呢?
*因为这些方法必须标识所属的锁,任意对象可以调用的方法必然是object类中的方法
*/
//描述生产者 属性:名称 编号 行为: 对名称进行赋值 获取商品
class Resource
{
private String name ;
private int count = 1;
// 定义标记
private boolean flag = false ;

//数据错误 已经被生产了很早的问题,才被消费到    出现了线程安全问题,用同步解决问题

// 解决方式 同步函数和同步代码块

// 提供设置方法
public synchronized void set(String name)
{
if(flag)
try {this.wait();} catch (InterruptedException e) {}
// 给成员变量赋值并加上编号
this.name = name + count ;
// 编号自增
count++ ;
System.out.println(Thread.currentThread().getName()+”…生产者…”+this.name);
flag = true ;//将标记改为真
//唤醒消费者
this.notify();
}
public synchronized void out()
{
if(!flag)
try {this.wait();} catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName()+”…消费者…”+this.name);
flag = false;//将标记改为假
//唤醒生产者
this.notify();
}
}
//描述生产者 处理资源
class Producer implements Runnable
{
private Resource r ;
//生产者一初始化就有资源,需要将资源传递到构造函数中
Producer(Resource r)
{
this.r = r ;
}
public void run()
{
while(true){
r.set(“mianbao”);}
}
}
//描述消费者 处理资源
class Consumer1 implements Runnable
{
private Resource r ;
//消费者一初始化就有资源,需要将资源传递到构造函数中
Consumer1(Resource r)
{
this.r = r ;
}
public void run()
{
while(true)
{
r.out();
}
}
}

猜你喜欢

转载自blog.csdn.net/mingxu_W/article/details/81710507