2 cuilll cuilll 于 2016.03.06 17:00 提问

没有加同步出现了线程死 但是即使不加同步,也不会产生死锁的呀!!! 求大神 3C

package com.thread;

public class ThreadCommunicationDeadLock {

public static void main(String[] args) {


    Resource resource=new Resource();
    Thread t1=new Thread(new Producer(resource));
    Thread t2=new Thread(new CCustomer(resource));

    t1.start();
    t2.start();

}

}

class Resource {
private int count = 0;
private String name = "apple";
boolean flag=false;//flag标记 默认没有生产

public void set() {

        count++;
        System.out.println("producer"+Thread.currentThread().getName() +" ..."+ name + "--" + count);



}

/**
 * @return the flag
 */
public boolean getFlag() {
    return flag;
}

/**
 * @param flag the flag to set
 */
public void setFlag(boolean flag) {
    this.flag = flag;
}

public void out() {
    System.out.println("customer"+Thread.currentThread().getName() +"..."+ name + "--" + count);


}

}

class Producer implements Runnable {

Resource resource = null;

public Producer(Resource resource) {
    this.resource = resource;
}

@Override
public void run() {

    while (true) {



        if (resource.flag==false) {

            resource.set();

            resource.setFlag(true);

        }

    }

}

}

class CCustomer implements Runnable {
Resource resource = null;

public CCustomer(Resource resource) {
    super();
    this.resource = resource;
}

@Override
public void run() {

    while(true)
    {

        if (resource.flag==true) {
                resource.out();
                resource.setFlag(false);

        }
    }

}

}

7个回答

qq_20039385
qq_20039385   2016.03.06 18:39

while (true) 两个死循环,你机器吃得消吗。

cuilll
cuilll 同一时刻,flag标记不是true,就是false 对吧 ,你可以打印这个标记发现, Producer打印出来的都是false 二customer打印出来的都是true
2 年多之前 回复
qq_34111510
qq_34111510   2016.03.06 17:15

你这程序太乱,看不懂。写个线程有这么复杂吗

cuilll
cuilll 生产者生产一个,消费者 打印一个(ID)
2 年多之前 回复
qq_34111510
qq_34111510   2016.03.06 17:19

用锁旗标控制死锁问题啊,这个自己研究去。可以加我qq,9215695

qq_20039385
qq_20039385   2016.03.06 17:58

你这只是加了if判断的标记,跟多线程的锁没关系,你把锁的概念理解错啦,还有 if (resource.flag==true)直接 if (resource.flag)这样写就可以,多看看书。

cuilll
cuilll   2016.03.06 19:23

package com.thread;

import javax.net.ssl.SSLException;

public class ThreadCommunicationDeadLock {

public static void main(String[] args) {


    Resource resource=new Resource();
    Thread t1=new Thread(new Producer(resource));
    Thread t2=new Thread(new CCustomer(resource));

    t1.start();
    t2.start();

}

}

class Resource {
private int count = 0;
private String name = "apple";
boolean flag=false;//flag标记 默认没有生产

public void set() {

        count++;
        System.out.println("producer"+Thread.currentThread().getName() +" ..."+ name + "--" + count);



}

/**
 * @return the flag
 */
public boolean getFlag() {
    return flag;
}

/**
 * @param flag the flag to set
 */
public void setFlag(boolean flag) {
    this.flag = flag;
}

public void out() {
    System.out.println("customer"+Thread.currentThread().getName() +"..."+ name + "--" + count);


}

}

class Producer implements Runnable {

Resource resource = null;

public Producer(Resource resource) {
    this.resource = resource;
}

@Override
public void run() {

int times=0;
while (true) {

// System.out.println("Producer"+resource.flag);

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

                if (resource.flag==false) {

                    resource.set();
//              times++;
                    resource.setFlag(true);

                }

// if (times>5) {
//// break;
// }

    }

}

}

class CCustomer implements Runnable {
Resource resource = null;

public CCustomer(Resource resource) {
    super();
    this.resource = resource;
}

int times=0;
public void run() {

    while(true)
    {

// System.out.println("cus"+resource.flag);

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

                if (resource.flag==true) {
                    resource.out();

// times++;
resource.setFlag(false);

                }

// if (times>5) {
//// break;
// }
}

}

}
休眠了一毫秒,程序就能正常运行了,这是为什么..........................@
休眠了一毫秒,程序就能正常运行了,这是为什么..........................@
休眠了一毫秒,程序就能正常运行了,这是为什么..........................@

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.03.06 22:09

同步操作使用锁不当,才会产生死锁问题。你这段代码没有同步操作,当然不会有死锁问题 。但是会有数据不一致问题。
你这段代码,生产者线程和消费者线程共享了Resource这个对象,所以对这个对象访问时需要作同步处理,才能保证数据的一致性。即你的Resource类的方法需要用同步处理。
你的代码就是休眠一秒,继续执行的啊,根本没有锁竞争问题。

broust
broust   2016.03.07 11:09

1.没死锁,是被你自己的代码轮死的。两个while(true)直接把cpu耗尽了.中间加个Thread.sleep(100)看看
2.Resource.flag需要设置成volatile,否则线程不可见。或则使用AtomicBoolean也行。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
Java 线程同步与死锁 学习笔记
Java 线程同步与死锁 学习笔记Java 线程同步与死锁 学习笔记 1 多线程共享数据 2 线程同步 3 同步准则 4 线程死锁 1、 多线程共享数据 在多线程操作中,多个线程可能同时处理同一个资源,这就是多线程中的共享数据。如:在对数据库进行操作中,有可能同时会有多个线程同时对某个数据进行操作 eg:public class MyThread implements Runnable{
Java 多线程同步与死锁
在多线程中如何找到安全问题所在: 1,明确哪些代码是多线程运行代码 2,明确共享数据 3,明确多线程运行代码中哪些代码是操作共享数据的 静态的同步方法中,使用锁是该方法所在类的字节码文件对象,即 类名.class  前天俺们谈到了加锁,但是在使用加锁的同时又会带来一个问题,就是死锁。什么叫死锁? 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而
多线程同步与死锁深入分析
多线程同步与死锁深入分析 前言 在多线程开发中,同步与死锁是非常重要的,在本篇文章中,读者将会明白一下几点: 1、哪里需要同步 2、如何实现同步 3、以及实现同步之后会有哪些副作用 例子 问题的引出 以买火车票为例,如果现在要是想买火车票的话可以去火车站买或者各个售票点,但是不管多少个地方可以买火车票,最终一趟列车的车票数是固定的,如果把各个
多线程——同步嵌套造成死锁问题
package com.qianfeng.demo02; /** * 同步的另外一个弊端:死锁 * * 最常见的死锁的情况: * 同步嵌套,同步中还有同步,然后两个同步用的不是一把锁。 * * 不是使用死锁,而是避免死锁。 * * 尽量避免同步嵌套的情况。 * */ public class DeadLockDemo01 { public static void mai
有10个资源,10个线程,如何保证不会出现死锁?
今天面试遇到这样一个题:有10个资源,10个线程,如何保证不会出现死锁?在解决问题之前,先了解下产生死锁的四个必要条件: 1. 互斥条件。在一段时间内,某资源只能被一个进程占用。如果此时还有其他进程请求该资源,则请求进程只能等待,直至占用该资源的进程使用完毕后释放。 2. 请求和保持条件。进程至少保持一个资源,但又提出了新的资源请求,而该资源已被其他进程占用,此时请求进程被阻塞,蛋碎玉自己已获得
Java多线程 线程同步与死锁
1.线程同步多线程引发的安全问题一个非常经典的案例,银行取钱的问题。假如你有一张银行卡,里面有5000块钱,然后你去银行取款2000块钱。正在你取钱的时候,取款机正要从你的5000余额中减去2000的时候,你的老婆正巧也在用银行卡对应的存折取钱,由于取款机还没有把你的2000块钱扣除,银行查到存折里的余额还剩5000块钱,准备减去2000。这时,有趣的事情发生了,你和你的老婆从同一个账户共取走了40
一些防止多线程同步造成死锁的技巧
-
Android 线程死锁的四个产生必要条件
死锁:死锁是指两个或两个以上的进程进在执行过程中,由于资源竞争或由于相互通信而造成的一种阻塞式现象,如果没有外力影响。那么它们将永远的持续下去, 此事称系统产生死锁现象,这种永远互相在等待的进程成为死锁。 死锁的四个产生必要条件: 1、互斥条件:进程对所分配到的资源具有排他性使用,一段时间内某资源只由一个进程所占有。若此时还有其他请求资源,则请求者只能等待,知道占有资源的进程使用完毕释
主队列中添加的同步操作永远不会被执行,会死锁原因
主队列在执行dispatch_sync,函数会把一个block加入到指定的队列,此函数要求执行完block才返回,函数要求此时去执行block内容,但是主队列此时还在卡在函数,函数线程还在,不能去执行block,也就是说函数和block是两个操作,在队列中前后关系。若是异步,函数添加完block就返回,顺序执行block内容,不存在死锁问题
[操作系统]复习四 进程 同步互斥 死锁
进程和程序的本质区别在于动态和静态特征   系统中感知进程的唯一实体是PCB(进程控制块,process control block)     进程状态转换:①运行②就绪③阻塞 运行:当一个进程在处理器上运行时,称其为运行状态,对于单处理器系统来说,处于运行状态的进程只有一个。在没有其他进程可执行时(比如所有进程都处于阻塞状态),通常会自动执行系统的空闲进程。 就绪:当一个进程获得了