在这个程序中, 两个不同的线程对同一个类的同一个对象进行操作
我想问的第一个问题是: 在这个多线程中同步到底是由谁来控制的? 是main 还是 Q不知道你什么意思,假如说要按照一定的顺序的话,应该是由java虚拟机来控制的同一个类中方法间的同步, 通过 wait 和 notify 来进行控制权的切换
线程间的切换通过sleep让出CPU来实现.
以上两句话正确吗?wait notify只是一个线程去唤醒另外一个线程
线程间的切换不是由sleep实现的,因为你即使不sleep,你一个线程占用一定的cpu的时间片以后也必须切换到其他线程,而且sleep不是可靠的,也就是说你让一个线程sleep一秒,一秒以后它不一定能够立即被执行.wait执行后, 是像函数那样原地等待回复呢? 还是结束这个同步方法(块), 下次重头再来过?
notify激活后到哪里去执行?
wait以后线程进入等待状态,下次执行的时候从wait代码以下的部分开始做,不是从头再来如果有3个(或以上)的线程, 要求按照我的次序依次执行, 该怎么去做, 怎么做比较的方便.
能提供一简单的例题吗?
你也可以用wait和notify来实现我学线程的时候也很头疼,http://blog.csdn.net/squall1009/archive/2004/11/14/181409.aspx希望这篇日记对你有帮助
我想问的第一个问题是: 在这个多线程中同步到底是由谁来控制的? 是main 还是 Q不知道你什么意思,假如说要按照一定的顺序的话,应该是由java虚拟机来控制的同一个类中方法间的同步, 通过 wait 和 notify 来进行控制权的切换
线程间的切换通过sleep让出CPU来实现.
以上两句话正确吗?wait notify只是一个线程去唤醒另外一个线程
线程间的切换不是由sleep实现的,因为你即使不sleep,你一个线程占用一定的cpu的时间片以后也必须切换到其他线程,而且sleep不是可靠的,也就是说你让一个线程sleep一秒,一秒以后它不一定能够立即被执行.wait执行后, 是像函数那样原地等待回复呢? 还是结束这个同步方法(块), 下次重头再来过?
notify激活后到哪里去执行?
wait以后线程进入等待状态,下次执行的时候从wait代码以下的部分开始做,不是从头再来如果有3个(或以上)的线程, 要求按照我的次序依次执行, 该怎么去做, 怎么做比较的方便.
能提供一简单的例题吗?
你也可以用wait和notify来实现我学线程的时候也很头疼,http://blog.csdn.net/squall1009/archive/2004/11/14/181409.aspx希望这篇日记对你有帮助
请问这两者间有何区别?
我的理解是:
wait的线程只能通过其他进程中的notify来唤醒,
而被sleep的线程当得到轮换的时间片后会被自动唤醒.
这么说对吗?我为什么要wait 是暂存区中无数据可取
if(!bFull) // 暂存区中无数据可提取, 控制权移交
{ try{ wait();} catch(Exception e){} }
照阁下所说 "wait以后线程进入等待状态,下次执行的时候从wait代码以下的部分开始做,不是从头再来", 如果我我有十个进程, 只有一个是写数据的, 9个读数据. 是有谁能保证回来的时候肯定是bFull=true?
我认为应该是从头来过.
还是求一个同时执行3个(以上)线程的样本程序.
读线程不是头疼的问题, 是杀头的问题了.
我看整本<<Java核心技术卷一>>都比这轻松.
什么乱七八糟的, 这怎么是面向对象呢, 完全是面向过程嘛.
难, 实在是太难了.感谢阁下的帮助, 我想再等几个回复, 到时候一块给分, 先谢了.
而被sleep的线程当得到轮换的时间片后会被自动唤醒.
这么说对吗?wait能保证被notify的线程立刻被运行,但你一个线程假如sleep(1000)的话,1000毫秒以后不能保证它立刻开始运行
* Created on 2005-2-12
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package test;/**
* @author SquallStar
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/class Producer implements Runnable // 输入
{
public Producer(Q q) // 传入的是一个Q的对象
{
this.q = q; // 使用另一个类中的方法
}
public void run()
{
boolean i = false;
while(true)
{
if( i )
q.put("Z3","male");
else
q.put("L4","famale");
i = !i; // 交替放入"Z3"和""L4"
try{ Thread.sleep(1000); } catch(Exception e){}
}
}
private Q q;
}class Consumer implements Runnable // 输出
{
public Consumer(Q q)
{
this.q=q;
}
public void run()
{
while(true)
{
q.get();
try{ Thread.sleep(1000); } catch(Exception e){}
}
}
private Q q;
}class Q // 这个线程是安全的
{
// 同类两方法的同步, 要比两个类中的同步简单的多
public synchronized void put(String name, String sex)
{
if(bFull) // 输入的数据还未被输出, 再输入的话会覆盖原数据造成数据丢失. 通过wait方法将控制权交出.
{ try{
System.out.println("Before Wait in put!");
wait();
System.out.println("After Wait in put!");
} catch(Exception e){} }
// Object.wait 等待这个对象另一个更改线程的通知.
// 问题A: wait执行后, 是像函数那样原地等待回复呢? 还是结束这个同步方法(块), 下次重头再来过? 从wait以后可以做
// 我认为是后者, 不知对不对?
this.name = name;
// try{ Thread.sleep(1); } catch(Exception e){} // 整个方法同步, 此举无意义
this.sex = sex;
bFull=true;
notify(); // Object.notify 激活等待在该对象的监视器上的一个线程
// 问题B: notify激活后到哪里去执行 888 或 999 从666开始做
}
public synchronized void get() // 888
{
if(!bFull) // 暂存区中无数据可提取, 控制权移交
{
try{
System.out.println("Before Wait in get!");
wait(); // 666
System.out.println("After Wait in get!");
}
catch(Exception e){}
}
// 999
System.out.print(name);
System.out.println(" : " + sex); // 同类中, q必须去掉
bFull = false;
notify();
}
private String name = "unknown";
private String sex = "unknown";
private boolean bFull = false;
}public class ThreadCommunation
{
public static void main(String[] args)
{
Q q = new Q(); // 同一对象的两个线程
new Thread(new Producer(q)).start();
new Thread(new Consumer(q)).start();
}
}
A. 线程同步不存在主控权问题,main函数把两个线程启动后,两个线程之间就变成了典型的producer/consumer关系,这两个线程的调度是由java 虚拟机完成,同步时由虚拟机的同步机制,也就是notify, wait来完成的。
Q. 同一个类中方法间的同步, 通过 wait 和 notify 来进行控制权的切换
线程间的切换通过sleep让出CPU来实现.
以上两句话正确吗?
A. notify, wait不是用于同一个类中方法间的控制权切换,而是用于两个(组)不同线程之间的控制权切换。
通过sleep让出cpu是线程切换的一种方式,还有java 虚拟机主动调度和前面所说的wait, notify等。
Q. wait执行后, 是像函数那样原地等待回复呢? 还是结束这个同步方法(块), 下次重头再来过?
notify激活后到哪里去执行?
A. wait执行后,当前线程即终止执行,程序指令指针自然指向wait后的第一条指令,下次该线程被唤醒,就从wait后开始执行。
notify激活的可能不止一个线程,由虚拟机调度其中的一个投入运行,也就是被调度的线程的wait后面的代码。Q. 如果有3个(或以上)的线程, 要求按照我的次序依次执行, 该怎么去做, 怎么做比较的方便.
能提供一简单的例题吗?
A. 不明白,如果要三个线程按要求依次执行,为什么不干脆在一个线程中依次完成。如果非要这样实现,我的建议是,若三个线程为a, b, c,则在a中启动b,b中启动c。 照阁下所说 "wait以后线程进入等待状态,下次执行的时候从wait代码以下的部分开始做,不是从
头再来", 如果我我有十个进程, 只有一个是写数据的, 9个读数据. 是有谁能保证回来的时候肯定
是bFull=true?
我认为应该是从头来过.一个写数据的,哪怕n个读的都无所谓,当唤醒时,因为只有一个线程被真正唤醒,投入执行。强烈建议搂主先学习《操作系统》,这才是基础。
class Producer implements Runnable // 输入
{
public Producer(Q q) // 传入的是一个Q的对象
{
this.q = q; // 使用另一个类中的方法
}
public void run()
{
boolean i = false;
while(true)
{
if( i )
q.put("Z3","male");
else
q.put("L4","famale");
i = !i; // 交替放入"Z3"和""L4"
try{ Thread.sleep(1000); } catch(Exception e){}
}
}
private Q q;
}class Consumer implements Runnable // 输出
{
public Consumer(Q q)
{
this.q=q;
}
public void run()
{
while(true)
{
q.get();
try{ Thread.sleep(1000); } catch(Exception e){}
}
}
private Q q;
}class Q // 这个线程是安全的
{
// 同类两方法的同步, 要比两个类中的同步简单的多
public synchronized void put(String name, String sex)
{
if(bFull) // 输入的数据还未被输出, 再输入的话会覆盖原数据造成数据丢失. 通过wait方法将控制权交出.
{ try{ wait();} catch(Exception e){} }
// Object.wait 等待这个对象另一个更改线程的通知.
// 问题A: wait执行后, 是像函数那样原地等待回复呢? 还是结束这个同步方法(块), 下次重头再来过?
// 我认为是后者, 不知对不对?
------------------------------------------
//应该是前者。
this.name = name;
// try{ Thread.sleep(1); } catch(Exception e){} // 整个方法同步, 此举无意义
this.sex = sex;
bFull=true;
notify(); // Object.notify 激活等待在该对象的监视器上的一个线程
// 问题B: notify激活后到哪里去执行 888 或 999
--------------------------------------------
//应该是999
}public synchronized void get() // 888
{
if(!bFull) // 暂存区中无数据可提取, 控制权移交
{ try{ wait();} catch(Exception e){} }
// 999
System.out.print(name);
System.out.println(" : " + sex); // 同类中, q必须去掉
bFull = false;
notify();
}private String name = "unknown";
private String sex = "unknown";
private boolean bFull = false;
}class ThreadCommunation
{
public static void main(String[] args)
{
Q q = new Q(); // 同一对象的两个线程
new Thread(new Producer(q)).start();
new Thread(new Consumer(q)).start();
}