看看下面这个程序:class ThreadA
{
public static void main(String[] args)
{
ThreadB b=new ThreadB();
b.start();
System.out.println("b is start....");
synchronized(b)
{
try
{
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
}catch (InterruptedException e){}
}
System.out.println("Total is :"+b.total);
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(this)
{
System.out.println("ThreadB is running..");
for (int i=0;i<100;i++ )
{
total +=i;
System.out.println("total is "+total);
}
//this.notify();
}
}
}运行结果:
b is start....
Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
.....
total is 4851
total is 4950
Completed.Now back to main thread
Total is :4950疑问:由于B线程会sleep(2000).因此A线程会首先获得公共对象b的锁进入运行。然后打印System.out.println("Waiting for b to complete...");接着等待阻塞: b.wait();。此时线程A放弃b的锁。而线程B则进入循环运行,开始打印
ThreadB is running..
total is 0
total is 1
.....
total is 4851
total is 4950
但是很奇怪B线程运行完毕以后,并没有调用//this.notify();这个时候A线程是不是不会被激活?那么程序为什么可以正常结束而且打印了A线程中wait()之后的两条打印语句呢?
{
public static void main(String[] args)
{
ThreadB b=new ThreadB();
b.start();
System.out.println("b is start....");
synchronized(b)
{
try
{
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
}catch (InterruptedException e){}
}
System.out.println("Total is :"+b.total);
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(this)
{
System.out.println("ThreadB is running..");
for (int i=0;i<100;i++ )
{
total +=i;
System.out.println("total is "+total);
}
//this.notify();
}
}
}运行结果:
b is start....
Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
.....
total is 4851
total is 4950
Completed.Now back to main thread
Total is :4950疑问:由于B线程会sleep(2000).因此A线程会首先获得公共对象b的锁进入运行。然后打印System.out.println("Waiting for b to complete...");接着等待阻塞: b.wait();。此时线程A放弃b的锁。而线程B则进入循环运行,开始打印
ThreadB is running..
total is 0
total is 1
.....
total is 4851
total is 4950
但是很奇怪B线程运行完毕以后,并没有调用//this.notify();这个时候A线程是不是不会被激活?那么程序为什么可以正常结束而且打印了A线程中wait()之后的两条打印语句呢?
解决方案 »
- log4j 怎么用info输出到控制台
- 求简单的threadpool程序,急!
- 怪问题啊!怎么修改web.xml文件的路径
- 讨论一个问题:怎样避免一个类在不断地变化中对它相关联的类产生不利影响
- Strng..replaceAll("\t","CX65");如何把字符串中的\t替换为其他的字符?
- 问一个日期方面的问题?
- JAVA包的困惑(在线等待)
- 有关记录集的纪录数
- 请问java.sql.numeric是如何构造的?
- 天啊!这儿的高手对JAVA失去信心了,初学者怎么办啊?学C#?
- 正确改写equals的解决方案
- JTable中某列加入JCombobox,当移动到jcombobox后,用上下键选择jcombobox中的内容,但是却跳入jtable的下一行,求解决方法.如图
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}class ThreadB extends Thread {
int total; public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
System.out.println("ThreadB is running..");
this.notify();//在这里唤醒等待的线程,没用,因为这个现在还没有执行完
for (int i = 0; i < 100; i++) {
total += i;
System.out.println("total is " + total);
} }
}
}
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (b) {
try {
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}class ThreadB extends Thread {
int total; public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
System.out.println("ThreadB is running..");
// this.sleep(4000);
try {
this.wait();//改成这样既出现死锁状态,最好改成wati(time);
} catch (InterruptedException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
for (int i = 0; i < 100; i++) {
total += i;
System.out.println("total is " + total);
} }
}
}
http://topic.csdn.net/u/20091010/22/f3b47259-14c8-4250-b52b-8a57584a683c.html
这个帖子的代码我自己看过了,我修改如下:
class T2 extends Thread {
public void run() {
for (char i= 'A'; i< 'F'; ++i) {
synchronized(Main.lockObj) {
System.out.println(i);
// Main.lockObj.notify(); 注意我讲notify注释掉
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
如果我将T2中的notify注释掉,很明显整个代码的运行将出现死锁,这主要是因为T1中的Main.lockObj.wait();把t1线程阻塞之后没有Main.lockObj.notify();条语句将t1激活照成的t1永远无法运行的死锁。但LZ的疑问是:LZ的代码中ThreadB的 //this.notify();也被注释掉了,但运行的时候ThreadA并没有出现死锁,我还是不知道为什么,谢谢musiclee的热情解释!
那么在B调用this.notify(); 以下是api
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。
你看到一句没 "直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程" 虽然B线程主动的this.notify();但是B线程仍然没有执行完毕,他还占有线程锁。。所以A还是无法运行,直到它执行完,释放了锁以后,A才进行运行。
至于为什么B运行完毕后不显示的this.notify();A也可以运行,我估计A只要侦测到实例b的线程锁完毕 ,则线程A就会自动运行
因为this.notify()的意思并不是释放掉线程锁。this.notify()不等于释放线程锁,。。它是唤醒,不是释放! 及告诉A你可以来试试看看门上锁没,并不是把门的钥匙给了A结不结贴不重要,重要的是 把问题弄明白,(不然提问干什么 )呵呵 : )