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次 那么另外一个线程就 一直不能获得锁 (我猜测的)
{
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次 那么另外一个线程就 一直不能获得锁 (我猜测的)
解决方案 »
- 局部变量声明而不赋值,和赋值为null,在内存分配上有什么区别?
- swing中setTitle的用法
- 求 base64标准编码的 java代码实现
- The method addMouseListener(MouseListener) in the type Component is not applicab
- 变量区别
- 接口的问题
- 怎样才能用JAVA调用WINDOWS里的CMD 来实现两台机器的连接
- 如何解决jxls乱码中文问题
- 苦啊,呜呜。。。
- Jdk1.2.2中的jdbc-odbc桥不支持JDBC2.0特新了吗?
- 输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
- 快没信心了,学了很久,还是写不出一个小程序,给看一下这个猜字游戏代码吧,虚心求教啊
{
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();
} }
}
//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。
add1再运行,进入wait状态
add2运行,进入wait状态
sub2运行,然后i变成0,add1被notify
sub2运行,进入wait状态
add1运行,然后i变成1,但此时不一定是sub2被notify,如果是add2被notify,那么此后add1和add2都会进入wait状态,然后死锁出现死锁的原因是因为notify无法指定对象,解决这个现象的方法很简单,你把notify改为notifyAll就行了
{
A a = new A();
for (int i = 0; i<10000 ;i++)
{
(new Threadadd(a)).start();
(new Threadsub(a)).start();
}
}
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
这才是死锁:
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();
}
}