Skip to content

Commit

Permalink
补交第三次作业
Browse files Browse the repository at this point in the history
完成多线程下载
  • Loading branch information
Lizhny committed Mar 31, 2017
1 parent fcd09d2 commit 9cb7321
Show file tree
Hide file tree
Showing 13 changed files with 651 additions and 0 deletions.
32 changes: 32 additions & 0 deletions group26/lizhy2017/homework/third/basic/LRUPageFameTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package third.basic;

import org.junit.Assert;
import org.junit.Test;

/**
* ${}
* Created by spark_lizhy on 2017/3/31.
*/

public class LRUPageFameTest {
@Test
public void testAccess() {
LRUPageFrame frame = new LRUPageFrame(3);
frame.access(7);
frame.access(0);
frame.access(1);
Assert.assertEquals("1,0,7", frame.toString());
frame.access(2);
Assert.assertEquals("2,1,0", frame.toString());
frame.access(0);
Assert.assertEquals("0,2,1", frame.toString());
frame.access(0);
Assert.assertEquals("0,2,1", frame.toString());
frame.access(3);
Assert.assertEquals("3,0,2", frame.toString());
frame.access(0);
Assert.assertEquals("0,3,2", frame.toString());
frame.access(4);
Assert.assertEquals("4,0,3", frame.toString());
}
}
63 changes: 63 additions & 0 deletions group26/lizhy2017/homework/third/basic/LRUPageFrame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package third.basic;

/**
* ${}
* Created by spark_lizhy on 2017/3/31.
*/
/**
* 用双向链表实现 LRU 算法
* @author liuxin
*
*/
public class LRUPageFrame {

private static class Node {

Node prev;
Node next;
int pageNum;

Node() {
}
}

private int capacity;


private Node first;// 链表头
private Node last;// 链表尾


public LRUPageFrame(int capacity) {

this.capacity = capacity;

}

/**
* 获取缓存中对象
*
* @return
*/
public void access(int pageNum) {


}



public String toString(){
StringBuilder buffer = new StringBuilder();
Node node = first;
while(node != null){
buffer.append(node.pageNum);

node = node.next;
if(node != null){
buffer.append(",");
}
}
return buffer.toString();
}

}
125 changes: 125 additions & 0 deletions group26/lizhy2017/homework/third/basic/LinkedList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package third.basic;

/**
* ${}
* Created by spark_lizhy on 2017/3/31.
*/

public class LinkedList {

private Node head;

public void add(Object o){

}
public void add(int index , Object o){

}
public Object get(int index){
return null;
}
public Object remove(int index){
return null;
}

public int size(){
return -1;
}

public void addFirst(Object o){

}
public void addLast(Object o){

}
public Object removeFirst(){
return null;
}
public Object removeLast(){
return null;
}
// public Iterator iterator(){
// return null;
// }


private static class Node{
Object data;
Node next;

}

/**
* 把该链表逆置
* 例如链表为 3->7->10 , 逆置后变为 10->7->3
*/
public void reverse(){

}

/**
* 删除一个单链表的前半部分
* 例如:list = 2->5->7->8 , 删除以后的值为 7->8
* 如果 list = 2->5->7->8->10 , 删除以后的值为 7,8,10
*/
public void removeFirstHalf(){

}

/**
* 从第 i 个元素开始, 删除 length 个元素 , 注意 i 从 0 开始
* @param i
* @param length
*/
public void remove(int i, int length){

}
/**
* 假定当前链表和 listB 均包含已升序排列的整数
* 从当前链表中取出那些 listB 所指定的元素
* 例如当前链表 = 11->101->201->301->401->501->601->701
* listB = 1->3->4->6
* 返回的结果应该是 [101,301,401,601]
* @param list
*/
public int[] getElements(LinkedList list){
return null;
}

/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 从当前链表中中删除在 listB 中出现的元素
* @param list
*/

public void subtract(LinkedList list){

}

/**
* 已知当前链表中的元素以值递增有序排列,并以单链表作存储结构。
* 删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同)
*/
public void removeDuplicateValues(){

}

/**
* 已知链表中的元素以值递增有序排列,并以单链表作存储结构。
* 试写一高效的算法,删除表中所有值大于 min 且小于 max 的元素(若表中存在这样的元素)
* @param min
* @param max
*/
public void removeRange(int min, int max){

}

/**
* 假设当前链表和参数 list 指定的链表均以元素依值递增有序排列(同一表中的元素值各不相同)
* 现要求生成新链表 C,其元素为当前链表和 list 中元素的交集,且表 C 中的元素有依值递增有序排列
* @param list
*/
public LinkedList intersection( LinkedList list){
return null;
}
}
51 changes: 51 additions & 0 deletions group26/lizhy2017/homework/third/download/DownloadThread.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package third.download;


import java.io.IOException;
import java.io.RandomAccessFile;

import third.download.api.Connection;
import third.download.api.ConnectionException;
import third.download.api.DownloadListener;

public class DownloadThread extends Thread {

private RandomAccessFile accessFile;
private DownloadListener listener;
private Connection conn;
private int startPos;
private int endPos;

public DownloadThread(Connection conn, int startPos, int endPos, DownloadListener listener) {
this.listener = listener;
this.conn = conn;
this.startPos = startPos;
this.endPos = endPos;

}

public void run() {
try {
byte[] bytes = conn.read(startPos, endPos);
accessFile = new RandomAccessFile("./" + conn.getFileName(), "rw");
accessFile.seek(startPos);
accessFile.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} catch (ConnectionException e) {
e.printStackTrace();
} finally {
if (null != accessFile)
try {
accessFile.close();
} catch (IOException e) {
e.printStackTrace();
}

if (null != conn)
conn.close();
if (null != listener)
listener.notifyFinished();
}
}
}
86 changes: 86 additions & 0 deletions group26/lizhy2017/homework/third/download/FileDownloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package third.download;

import java.util.concurrent.atomic.AtomicInteger;

import third.download.api.Connection;
import third.download.api.ConnectionException;
import third.download.api.ConnectionManager;
import third.download.api.DownloadListener;


public class FileDownloader {
private final static int THREAD_NUM=15;
private String url;
private DownloadListener listener;
private ConnectionManager cm;
private AtomicInteger atomicInteger=new AtomicInteger();

public FileDownloader(String _url) {
this.url = _url;

}

public void execute(){
// 在这里实现你的代码, 注意: 需要用多线程实现下载
// 这个类依赖于其他几个接口, 你需要写这几个接口的实现代码
// (1) ConnectionManager , 可以打开一个连接,通过Connection可以读取其中的一段(用startPos, endPos来指定)
// (2) DownloadListener, 由于是多线程下载, 调用这个类的客户端不知道什么时候结束,所以你需要实现当所有
// 线程都执行完以后, 调用listener的notifiedFinished方法, 这样客户端就能收到通知。
// 具体的实现思路:
// 1. 需要调用ConnectionManager的open方法打开连接, 然后通过Connection.getContentLength方法获得文件的长度
// 2. 至少启动3个线程下载, 注意每个线程需要先调用ConnectionManager的open方法
// 然后调用read方法, read方法中有读取文件的开始位置和结束位置的参数, 返回值是byte[]数组
// 3. 把byte数组写入到文件中
// 4. 所有的线程都下载完成以后, 需要调用listener的notifiedFinished方法

// 下面的代码是示例代码, 也就是说只有一个线程, 你需要改造成多线程的。
Connection conn = null;
try {
int length = cm.getContentLength(url);
int perTread_lenth=length/THREAD_NUM;
int redundant=length%THREAD_NUM;
for (int i=0;i<THREAD_NUM;i++){
int startPos=i*perTread_lenth;
int endPos=(i+1)*perTread_lenth-1;
if (i==THREAD_NUM-1)
endPos+=redundant;
}
conn = cm.open(this.url);
atomicInteger.getAndIncrement();
new DownloadThread(conn, 0, length - 1, new DownloadListener() {
@Override
public void notifyFinished() {
if (atomicInteger.decrementAndGet()==0){
listener.notifyFinished();
}
}
}).start();

} catch (ConnectionException e) {
e.printStackTrace();
}finally{
if(conn != null){
conn.close();
}
}




}

public void setListener(DownloadListener listener) {
this.listener = listener;
}



public void setConnectionManager(ConnectionManager ucm){
this.cm = ucm;
}

public DownloadListener getListener(){
return this.listener;
}

}
Loading

0 comments on commit 9cb7321

Please sign in to comment.