java多线程共同操作同一个队列,怎么实现?

Python013

java多线程共同操作同一个队列,怎么实现?,第1张

具体代码如下:

以下是两个线程

import java.util.*

public class Thread_List_Operation {

//假设有这么一个队列

static List list = new LinkedList()

public static void main(String[] args) {

Thread t

t = new Thread(new T1())

t.start()

t = new Thread(new T2())

t.start()

}

}

//线程T1,用来给list添加新元素

class T1 implements Runnable{

void getElemt(Object o){

Thread_List_Operation.list.add(o)

System.out.println(Thread.currentThread().getName() + "为队列添加了一个元素")

}

@Override

public void run() {

for (int i = 0i <10i++) {

getElemt(new Integer(1))

}

}

}

//线程T2,用来给list添加新元素

class T2 implements Runnable{

void getElemt(Object o){

Thread_List_Operation.list.add(o)

System.out.println(Thread.currentThread().getName() + "为队列添加了一个元素")

}

@Override

public void run() {

for (int i = 0i <10i++) {

getElemt(new Integer(1))

}

}

}

//结果(乱序)

Thread-0为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-1为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

Thread-0为队列添加了一个元素

java中的消息队列

消息队列是线程间通讯的手段:

import java.util.*

public class MsgQueue{

private Vector queue = null

public MsgQueue(){

queue = new Vector()

}

public synchronized void send(Object o)

{

queue.addElement(o)

}

public synchronized Object recv()

{

if(queue.size()==0)

return null

Object o = queue.firstElement()

queue.removeElementAt(0)//or queue[0] = null can also work

return o

}

}

因为java中是locked by object的所以添加synchronized 就可以用于线程同步锁定对象

可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类

Java的多线程-线程间的通信2009-08-25 21:58

1. 线程的几种状态

线程有四种状态,任何一个线程肯定处于这四种状态中的一种:

1) 产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。

2) 可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。

3) 死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。

4) 停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。

2. class Thread下的常用函数函数

2.1 suspend()、resume()

1) 通过suspend()函数,可使线程进入停滞状态。通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。

2) 当调用suspend()函数后,线程不会释放它的“锁标志”。

例11:

class TestThreadMethod extends Thread{

public static int shareVar = 0

public TestThreadMethod(String name){

super(name)

}

public synchronized void run(){

if(shareVar==0){

for(int i=0i<5i++){

shareVar++

if(shareVar==5){

this.suspend() //(1)

}}}

else{

System.out.print(Thread.currentThread().getName())

System.out.println(" shareVar = " + shareVar)

this.resume() //(2)

}}

}

public class TestThread{

public static void main(String[] args){

TestThreadMethod t1 = new TestThreadMethod("t1")

TestThreadMethod t2 = new TestThreadMethod("t2")

t1.start() //(5)

//t1.start() //(3)

t2.start() //(4)

}}

一、需求    1.定时抓取固定网站新闻标题、内容、发表时间和来源。

    2.程序需要支持分布式、多线程 二、设计   1.网站是固定,但是未来也可能添加新的网站去抓取,每个网站内容节点设计都不一样,这样就需要支持动态可配置来新增网站以方便未来的扩展,这样就需要每次都需要开发介入。

    2.网站html节点的结构可能发生变化,所以也要支持提取节点可配置。

    3.怎样支持分布式?暂时最简单的想法就是:多机器部署程序,还有新搞一台或者部署程序其中一台制作一个定时任务,定时开启每台机器应该抓取哪个网站,暂时不能支持同一个网站同时可以支持被多台机器同时抓取,这样会比较麻烦,要用到分布式队列。

所以暂时一个网站同时只会被单台机器抓取。

    4.多线程,怎样多线程?多线程抓取我这边有两个实现:        (1)一个线程抓取一个网站,维护一个自己的url队列做广度抓取,同时抓取多个网站。

如图:                   (2)多个线程同时抓取不同的网站。

如图:       以上两张办法其实各有优点,也给有缺点,看我们怎么取舍了。

       方法1:每个线程创建一个自己的队列,图中的queue可以不用concurrentQueue,优点:不涉及到控制并发,每个网站一个线程抓取一个网站,抓取完毕即自动回收销毁线程。

控制方便。

缺点:线程数不可以扩展,例如当只有3个网站,你最多只能开3个线程来抓取,不能开更多,有一定的局限性。

       方法2:N个线程同时抓取N个网站,线程数和网站数目不挂钩,优点:线程数可以调整并且和和抓取网站数量无关。

3个网站我们可以开4个5个或者10个这个可以根据您的硬件资源进行调整。

缺点:需要控制并发,并且要控制什么时候销毁线程(thread1空闲,并且queue为空不代表任务可以结束,可能thread2结果还没返回),当被抓取的网站响应较慢时,会拖慢整个爬虫进度。

 三、实现    抓取方式最终还是选择了方法二,因为线程数可配置!     使用技术:          jfinal用了之后才发现这东西不适合,但是由于项目进度问题,还是使用了。

          maven项目管理          jettyserver          mysql          eclipse开发     项目需要重点攻破的难点:          (1)合理的控制N个线程正常的抓取网站,并且当所有线程工作都完成了并且需要抓取的队列为空时,N个线程同时退出销毁。

          (2)不同网站设计节点不一样,需要通过配置解决各个网站需要抓取的URL和抓取节点内容在html节点的位置。

          (3)个性化内容处理,由于html结构设计问题,北大青鸟http://www.kmbdqn.cn/认为抓取的内容可能有些多余的html标签,或者多余的内容该怎么处理。