首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java相关 >

求帮助 小弟我想让N条线程不用wait()的放数据 然后一条线程监控到有放数据就去取数据.

2012-12-16 
求帮助 我想让N条线程不用wait()的放数据 然后一条线程监控到有放数据就去取数据..本帖最后由 Ahimsa0o 于

求帮助 我想让N条线程不用wait()的放数据 然后一条线程监控到有放数据就去取数据..
本帖最后由 Ahimsa0o 于 2012-12-02 23:23:36 编辑
其实我想让N条线程不用wait()的放数据 
然后一条线程监控到有放数据就去取数据的..
结果写成这样勒....
import java.util.ArrayList;
/**定义一个类  一个存数据一个取数据*/
public class MonitorAccess {
private static ShareData data22 = new ShareData();
protected static Object data;
public static void main(String[] args){
Thread.currentThread();
for(int i=0;i<10;i++){
new Thread(new Runnable(){

public void run() {
data22.putData(data);
}

}
).start();
new Thread(new Runnable(){

public void run() {
data22.getData(data);
}

}
).start();
}
}
/**两个线程一个放数据一个取数据 */
class AddThread extends Thread{
private ShareData d;
public AddThread(ShareData p){
this.d=p;
}
public void run(){
data22.putData(data);}
}
class GetThread extends Thread{
private ShareData d;
public GetThread(ShareData p){
this.d=p;
}
public void run(){
data22.getData(data);}
}
}

class ShareData {

ArrayList datas = new ArrayList();
private boolean isputall = false;//数据是否放完

public synchronized void putData(Object a) {
for(int i = 0;i<3;i++){
datas.add(a);
notify();
}
/**放数据*/
isputall = true;
}
public synchronized void getData(Object a) {
while(datas.size()==0){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
/**取数据*/

if(isputall = true){
datas.clear();
}
isputall = false;
}
}


[最优解释]
改了改代码,不知是否符合楼主要求,参考一下:

import java.util.ArrayList;
/**定义一个类  一个存数据一个取数据*/
public class MonitorAccess
{
private static ShareData data22 = new ShareData();
protected static Object data;
public static void main(String[] args)
{
//Thread.currentThread();  //没用
for(int i=0;i<10;i++)//定义并启动10条存线程.
{
new Thread(new Runnable()
{
public void run() 
{
while(true)//无限循环
{
try{Thread.sleep(1000);}catch(InterruptedException ie){};
data22.putData(data);
}
}
}).start();
}
new Thread(new Runnable()
{
public void run()
{
while(true)//无限循环。
{
data22.getData(data);
}
}
}).start();
}
}

/*两个线程一个放数据一个取数据 //这两个都不需要.

class AddThread extends Thread{
private ShareData d;
public AddThread(ShareData p){
this.d=p;
}
public void run(){
data22.putData(data);}
}
class GetThread extends Thread{
private ShareData d;
public GetThread(ShareData p){
this.d=p;
}
public void run(){
data22.getData(data);}
}
}
*/
class ShareData
{
static int j=0;


ArrayList datas = new ArrayList();
private boolean isputall = false;//数据是否放完
public synchronized void putData(Object a)
       {
if(datas.size()==0)//只有容器空时才存.
{
for(int i = 0;i<3;i++)
{
datas.add(a);
}

/**放数据*/
isputall = true;
System.out.println("This is the "+j+" times putting!"+//输出点内容看看.
Thread.currentThread().getName());
notify();
}
}

public synchronized void getData(Object a)
{
while(datas.size()==0)
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
/**取数据*/

if(isputall = true)
{
datas.clear();
}
isputall = false;
System.out.println("This is the "+(j++)+" times getting!"
+Thread.currentThread().getName());
}
}


[其他解释]
谢谢你提醒 我改了一下程序

import java.util.ArrayList;

/**定义一个MonitorAcess类  可以监控存数据和取数据*/
public class MonitorAccess {

/**
 * @param args
 */
private static ShareData data22 = new ShareData();
protected static Object data;
public static void main(String[] args){
Thread.currentThread();
for(int i=0;i<5;i++){
new Thread(new Runnable(){

public void run() {
// N条放数据的线程
data22.putData(data);
}

}
).start();
}//for
new Thread(new Runnable(){

public void run() {
// 一条取数据的线程
data22.getData(data);
}

}
).start();

}

}

/**封装放数据和取数据的方法*/
class ShareData {

/**
 * @param args
 */

ArrayList<Object> datas = new ArrayList<Object>();
private boolean isputall = false;//数据是否放完

public synchronized void putData(Object a) {
for(int i = 0 ;i <3;i++){
datas.add(a);//往队列中放数据
notify();//唤醒阻塞队列的某个线程到就绪队列
System.out.println(Thread.currentThread().getName() + " 交易线程: 放数据 " +datas.toString());
isputall = true;
}
}

public synchronized void getData(Object a) {
// TODO 自动生成方法存根
while(datas.size()==0){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
if(isputall = true){
System.out.println(Thread.currentThread().getName() + " 监控线程: 取数据 " +datas.toString());
datas.clear();
isputall = false;
}

}

}


运行结果是:
Thread-1 交易线程: 放数据 [null]
Thread-1 交易线程: 放数据 [null, null]
Thread-1 交易线程: 放数据 [null, null, null]
Thread-2 交易线程: 放数据 [null, null, null, null]
Thread-2 交易线程: 放数据 [null, null, null, null, null]
Thread-2 交易线程: 放数据 [null, null, null, null, null, null]
Thread-0 交易线程: 放数据 [null, null, null, null, null, null, null]


Thread-0 交易线程: 放数据 [null, null, null, null, null, null, null, null]
Thread-0 交易线程: 放数据 [null, null, null, null, null, null, null, null, null]
Thread-4 交易线程: 放数据 [null, null, null, null, null, null, null, null, null, null]
Thread-4 交易线程: 放数据 [null, null, null, null, null, null, null, null, null, null, null]
Thread-4 交易线程: 放数据 [null, null, null, null, null, null, null, null, null, null, null, null]
Thread-5 监控线程: 取数据 [null, null, null, null, null, null, null, null, null, null, null, null]
Thread-3 交易线程: 放数据 [null]
Thread-3 交易线程: 放数据 [null, null]
Thread-3 交易线程: 放数据 [null, null, null]

我想先把逻辑调出来然后再写具体取和放的方法...
运行的结果 只有一次取数据 以后再放的数据 都没有取出来
在getData方法里不是有个wait()方法么
我debug跟了一下 取过一次数据了以后那个getData线程就没有了 
putData方法里有notify()的呀 怎么就没有勒呢 
是不是有什么自动kill了get线程?

[其他解释]
你的代码就是那样的,取线程取完一次,就结束了.
要想让它一直取,这样:


               // 一条取数据的线程
                while(true)
                {
                       data22.getData(data);
                }
            }

另外,存放线程一旦5个运行完也结束了。
建议也放在while(true)循环里。

[其他解释]
啊 这里忘了...谢谢 调出来了

热点排行