package com.thread;public class ThreadTest7
{
public static void main(String args[])
{
A a = new A();
Threadadd tadd1 = new Threadadd(a);
Threadadd tadd2 = new Threadadd(a);
Threadsub tsub1 = new Threadsub(a);
Threadsub tsub2 = new Threadsub(a); tadd1.start();
 tadd2.start();
tsub2.start();
// tsub1.start();
}}class A
{
private int i; public synchronized void increased()
{
// synchronized (this)
// {
// if ((i >= 1) || (i < 0))
if (0 != i)
{
try
{
// System.out.println("when increase value ,beyond our line .."
// + i);
System.out
.println("-->increase method i value is " + i
+ " waiting thread "
+ Thread.currentThread().getName());
this.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
++i;
System.out.println(i+ " "+Thread.currentThread().getName());
this.notify();
}
// }
} public synchronized void decreased()
{
if (1 == i)
{
--i;
System.out.println(i +" "+Thread.currentThread().getName());
this.notify();
}
else
{
try
{
System.out.println("-->decreased method i value is " + i
+ " waiting thread" + Thread.currentThread().getName());
this.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}class Threadadd extends Thread
{
private A a; public Threadadd(A a)
{
this.a = a;
} public void run()
{
while (true)
{
try
{
Thread.sleep((long) Math.random() * 1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
a.increased();
} }
}class Threadsub extends Thread
{
private A a; public Threadsub(A a)
{
this.a = a;
} public void run()
{
while (true)
{
try
{
Thread.sleep((long) Math.random() * 1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
a.decreased();
} }
}
有一个规律 当3个线程的时候 如果锁 被2个线程释放2次  那么另外一个线程就 一直不能获得锁 (我猜测的)

解决方案 »

  1.   

    刚才找到根本原因是 waiting pool理的 线程太多了 没有别的线程出来notify 大家都在等着被notify 所以。。 一个临时的解决方案是 : 当waiting pool的个数太多了的时候 就主动发一个notify 。。 不是最好的方案 如果谁有更合适的方案请告诉我牙 。分数照给package com.thread;public class ThreadTest7
    {
    public static void main(String args[])
    {
    A a = new A();
    Threadadd tadd1 = new Threadadd(a);
    Threadadd tadd2 = new Threadadd(a);
    Threadsub tsub1 = new Threadsub(a);
    Threadsub tsub2 = new Threadsub(a); tadd1.start();
    tadd2.start();
    tsub2.start();
    tsub1.start();
    }}class A
    {
    private int i;
    private int count; // monitor the thread quatities in the waiting pool. public synchronized void increased()
    { if (0 != i)
    {
    try
    {
    // System.out.println("when increase value ,beyond our line .."
    // + i);
    System.out
    .println("-->increase method i value is " + i
    + " waiting thread "
    + Thread.currentThread().getName());
    // Thread.
    if ((++count) >= 3)
    {
    this.notify();
    }
    this.wait(); }
    catch (InterruptedException e)
    {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    else
    {
    ++i;
    System.out.println(i + " " + Thread.currentThread().getName());
    this.notify();
    }
    // }
    } public synchronized void decreased()
    {
    if (1 == i)
    {
    --i;
    System.out.println(i + " " + Thread.currentThread().getName());
    this.notify();
    }
    else
    {
    try
    {
    System.out.println("-->decreased method i value is " + i
    + " waiting thread" + Thread.currentThread().getName());
    if ((++count) >= 3)
    {
    this.notify();
    }
    this.wait();
    }
    catch (InterruptedException e)
    {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
    }class Threadadd extends Thread
    {
    private A a; public Threadadd(A a)
    {
    this.a = a;
    } public void run()
    {
    while (true)
    {
    try
    {
    Thread.sleep((long) Math.random() * 1000);
    }
    catch (InterruptedException e)
    {
    e.printStackTrace();
    }
    a.increased();
    } }
    }class Threadsub extends Thread
    {
    private A a; public Threadsub(A a)
    {
    this.a = a;
    } public void run()
    {
    while (true)
    {
    try
    {
    Thread.sleep((long) Math.random() * 1000);
    }
    catch (InterruptedException e)
    {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    a.decreased();
    } }
    }
      

  2.   

    去掉你所有的notify,wait就可以了
      

  3.   

                     tadd1.start();
    //tadd2.start();
    tsub2.start();
    // tsub1.start();这样一注释掉就可以了。为什么呢?你有个误区,不是被notify()所唤醒的线程一定是与这个线程执行相反动作的线程。拿你的死锁代码来说:
    tadd1.start();
    tadd2.start();
    tsub2.start();
    //  tsub1.start();
    有两个执行加法动作的线程,如果tadd1执行完加操作后notify()唤醒了tadd2线程(tsub2一定在wait状态,因为同一时间只能一个线程获得锁),这时候tadd1执行完代码了sleep去了,tadd2执行的代码如下:this.wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }然后它也去睡觉了是吧?然后tsub2永远都再wait状态了!这就是为什么你多个notify又可以了一下,不过上述情况依然会出现,还是会死锁。其中一个解决方案是去掉所有的wait,notify。
      

  4.   

    我终于看懂死锁的原因了我们从最一开始说起add1运行,然后i变成1
    add1再运行,进入wait状态
    add2运行,进入wait状态
    sub2运行,然后i变成0,add1被notify
    sub2运行,进入wait状态
    add1运行,然后i变成1,但此时不一定是sub2被notify,如果是add2被notify,那么此后add1和add2都会进入wait状态,然后死锁出现死锁的原因是因为notify无法指定对象,解决这个现象的方法很简单,你把notify改为notifyAll就行了
      

  5.   

    ......死锁个P。最后的那个线程Notify之后wait, 没有其他线程进行唤醒
      

  6.   

    谢谢各位 先说明一下 确实不是死锁... 因为锁一直有 但是没有线程去拿。当2个线程的时候 就不会出问题当3个线程的时候 就会出问题 根本原因 我看到的是 当waiting pool里 有3个 线程 都在等着 被notify 这个时候 就可以获得锁了 按照我的思路 100个线程 也不会问题了  哪位大虾 有更smart的代码么 
      

  7.   

    有发现一个问题 当线程数超过 40000的时候 整个电脑会死掉... 我的机器是 4核 内存 4g JDK 7 win7 64 public static void main(String args[])
    {
    A a = new A();

    for (int i = 0; i<10000 ;i++)
    {
     (new Threadadd(a)).start();
     (new Threadsub(a)).start();
    }
    }
      

  8.   

    并且我已经把 eclise 的内存加大到512-startup
    plugins/org.eclipse.equinox.launcher_1.2.0.v20110502.jar
    --launcher.library
    plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.100.v20110502
    -showsplash
    org.eclipse.platform
    --launcher.XXMaxPermSize
    512m
    --launcher.defaultAction
    openFile
    -vmargs
    -Xms40m
    -Xmx384m
      

  9.   

    你的代码是都在等待唤醒,死锁是互相等待对方持有的资源,又不肯主动放弃已经占有的资源,陷入无限等待的僵局。
    这才是死锁:
    public class DeadLock
    {
        private static final Object lockA = new Object();
        
        private static final Object lockB = new Object();
        
        public static void main(String[] args)
        {
            new Thread()
            {
                @Override
                public void run()
                {
                    synchronized (lockA)
                    {
                        System.out.println("T1:Get lockA");
                        try
                        {
                            Thread.sleep(1000L); // 等1秒,保证另外一个线程能拿到lockB
                        }
                        catch (InterruptedException e)
                        {
                        }
                        
                        synchronized (lockB)
                        {
                            System.out.println("T1:Get lockB");
                            System.out.println("T1:Get all lock");
                        }
                    }
                }
            }.start();
            
            new Thread()
            {
                @Override
                public void run()
                {
                    synchronized (lockB)
                    {
                        System.out.println("T2:Get lockB");
                        try
                        {
                            Thread.sleep(1000L); // 等1秒,保证另外一个线程能拿到lockA
                        }
                        catch (InterruptedException e)
                        {
                        }
                        
                        synchronized (lockA)
                        {
                            System.out.println("T2:Get lockA");
                            System.out.println("T2:Get all lock");
                        }
                    }
                }
            }.start();
        }
        
    }
      

  10.   

    补充:使用到了wait,就等于说是主动放弃了已经占有的锁,不符合死锁条件了
      

  11.   

    严重 同意 问题已经解决 notifyall() 就行了 我已经知道了 就是不能回复3次 谢谢了, 但是开线程太多的时候 机器会死 请问有何解释