java实现模拟多线程上传下载软件 java多线程上传文件
摘要:Java如何实现多线程传输文件,就像迅雷下载一样,开十多个线程分段 程序分Server和Client 服务器端打开侦听的端口,一有客户端连接就创建两个新的线程来负责这个连接 一个负责客户端发送的信...
发布日期:2020-10-21Java如何实现多线程传输文件,就像迅雷下载一样,开十多个线程分段...
程序分Server和Client 服务器端打开侦听的端口,一有客户端连接就创建两个新的线程来负责这个连接 一个负责客户端发送的信息(ClientMsgCollectThread 类),另一个负责通过该Socket发送数据(ServerMsgSendThread ) Server.java代码如下:/* * 创建日期 2009-3-7 * * TODO 要更改此生成的文件的模板,请转至 * 窗口 - 首选项 - Java - 代码样式 - 代码模板 */ package faue.MutiUser; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket;/** * 服务器端 * * @author Faue */ public class Server extends ServerSocket { private static final int SERVER_PORT = 10000; /** * 构造方法,用于实现连接的监听 * * @throws IOException */ public Server() throws IOException { super(SERVER_PORT); try { while (true) { Socket socket = super.accept(); new Thread(new ClientMsgCollectThread(socket), "getAndShow" + socket.getPort()).start(); new Thread(new ServerMsgSendThread(socket), "send" + socket.getPort()).start(); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { new Server(); } /** * 该类用于创建接收客户端发来的信息并显示的线程 * * @author Faue * @version 1.0.0 */ class ClientMsgCollectThread implements Runnable { private Socket client; private BufferedReader in; private StringBuffer inputStringBuffer = new StringBuffer("Hello"); /** * 得到Socket的输入流 * * @param s * @throws IOException */ public ClientMsgCollectThread(Socket s) throws IOException { client = s; in = new BufferedReader(new InputStreamReader(client .getInputStream(), "GBK")); } public void run() { try { while (!client.isClosed()) { inputStringBuffer.delete(0, inputStringBuffer.length()); inputStringBuffer.append(in.readLine()); System.out.println(getMsg(inputStringBuffer.toString())); } } catch (IOException e) { //e.printStackTrace(); System.out.println(client.toString() + " is closed!"); } } /** * 构造显示的字符串 * * @param line * @return */ private String getMsg(String line) { return client.toString() + " says:" + line; } } /** * 该类用于创建发送数据的线程 * * @author Faue * @version 1.0.0 */ class ServerMsgSendThread implements Runnable { private Socket client; private PrintWriter out; private BufferedReader keyboardInput; private StringBuffer outputStringBuffer = new StringBuffer("Hello"); /** * 得到键盘的输入流 * * @param s * @throws IOException */ public ServerMsgSendThread(Socket s) throws IOException { client = s; out = new PrintWriter(client.getOutputStream(), true); keyboardInput = new BufferedReader(new InputStreamReader(System.in)); } public void run() { try { while (!client.isClosed()) { outputStringBuffer.delete(0, outputStringBuffer.length()); outputStringBuffer.append(keyboardInput.readLine()); out.println(outputStringBuffer.toString()); } } catch (IOException e) { //e.printStackTrace(); System.out.println(client.toString() + " is closed!"); } } } } 客户端:实现基于IP地址的连接,连接后也创建两个线程来实现信息的发送和接收/* * 创建日期 2009-3-7 * */ package faue.MutiUser; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket;/** * 客户端 * * @author Faue */ public class Client { private Socket mySocket; /** * 创建线程的构造方法 * * @param IP * @throws IOException */ public Client(String IP) throws IOException { try { mySocket = new Socket(IP, 10000); new Thread(new ServerMsgCollectThread(mySocket), "getAndShow" + mySocket.getPort()).start(); new Thread(new ClientMsgSendThread(mySocket), "send" + mySocket.getPort()).start(); } catch (IOException e) { //e.printStackTrace(); System.out.println("Server.IP:" + IP + " port:10000 can not be Connected"); } } public static void main(String[] args) throws IOException { try { new Client(args[0]); } catch (Exception e) { System.out.println("输入的IP地址错误"); } } /** * 该类用于创建接收服务端发来的信息并显示的线程 * * @author Faue * @version 1.0.0 */ class ServerMsgCollectThread implements Runnable { private Socket client; private BufferedReader in; private StringBuffer inputStringBuffer = new StringBuffer("Hello"); /** * 得到Socket的输入流 * * @param s * @throws IOException */ public ServerMsgCollectThread(Socket s) throws IOException { client = s; in = new BufferedReader(new InputStreamReader(client .getInputStream(), "GBK")); } public void run() { try { while (!client.isClosed()) { inputStringBuffer.delete(0, inputStringBuffer.length()); inputStringBuffer.append(in.readLine()); System.out....
怎样使用java多线程机制实现下载?
package com.zly; impot java.io.FileOutputSteam; impot java.io.IOException; impot java.io.InputSteam; impot java.io.OutputSteam; impot java.net.HttpURLConnection; impot java.net.URL; 下载线程类 pulic class DownloadThead implements Runnale { 当前第几个线程 , 用于给下载文件起名 file1 file2 file3 ... pivate int whichThead ; 监听单一线程下载是否完成 pivate oolean isFinish ; 本线程要下载的文件字节数 pivate int length ; 本线程向服务器发送请求时输入流的首位置 pivate int statPosition; 保存的路径 pivate Sting savePath ; 要下载的文件 , 用于创建连接 pivate Sting ul; pulic void un() { HttpURLConnection conn = null; InputSteam in = null; OutputSteam out = null; ty { URL fileUl = new URL(ul); 与服务器创建连接 conn = (HttpURLConnection) fileUl.openConnection(); 下载使用get请求 conn.setRequestMethod("GET"); 告诉服务器 , 我是火狐 , 不要不让我下载。
conn.setRequestPopety("Use-Agent", "Fiefox Mozilla5.0 (Windows; U; Windows NT 5.1; zh-CN; v:1.9.1.3) Gecko20090824 Fiefox3.5.3"); 这里是设置文件输入流的首位置 conn.setRequestPopety("Range", "ytes=" + statPosition + "-"); 与服务器创建连接 conn.connect(); 获得输入流 in = conn.getInputSteam(); 在硬盘上创建file1 , file2 , ...这样的文件 , 准备往里面写东西 out = new FileOutputSteam(savePath + whichThead); 用于写入的字节数组 yte[] ytes = new yte[4096]; 一共下载了多少字节 int count = 0 ; 单次读取的字节数 int ead = 0 ; while((ead = in.ead(ytes)) != -1) { 检查一下是不是下载到了本线程需要的长度 if(length - count ytes.length) { 比如说本线程还需要900字节,但是已经读取1000 字节,则用要本线程总下载长度减去 已经下载的长度 ead = length - count; } 将准确的字节写入输出流 out.wite(ytes, 0, ead); 已经下载的字节数加上本次循环字节数 count = count + ead; 如果下载字节达到本线程所需要字节数,消除循环, 停止下载 if(count == length) { eak; } } 以上是我对于这个问题的解答,希望能够帮到大家。
Java语言多线程编程如何实现线程呢?
Thead 类是一个具体的类,即不是抽象类,该类封装了线程的行为。
要创建一个线程,程序员必须创建一个从 Thead 类导出的新类。
程序员必须覆盖 Thead 的 un() 函数来完成有用的工作。
用户并不直接调用此函数;而是必须调用 Thead 的 stat() 函数,该函数再调用 un()。
下面的代码说明了它的用法: 创建两个新线程 Copy codeimpot java.util.*;class TimePinte extends Thead { int pauseTime; Sting name; pulic TimePinte(int x, Sting n) { pauseTime = x; name = n; } pulic void un() { while(tue) { ty { System.out.pintln(name + ":" + new Date(System.cuentTimeMillis())); Thead.sleep(pauseTime); } catch(Exception e) { System.out.pintln(e); } } } static pulic void main(Sting ags[]) { TimePinte tp1 = new TimePinte(1000, "Fast Guy"); tp1.stat(); TimePinte tp2 = new TimePinte(3000, "Slow Guy"); tp2.stat(); } }在本例中,我们可以看到一个简单的程序,它按两个不同的时间间隔(1 秒和 3 秒)在屏幕上显示当前时间。
这是通过创建两个新线程来完成的,包括 main() 共三个线程。
但是,因为有时要作为线程运行的类可能已经是某个类层次的一部分,所以就不能再按这种机制创建线程。
虽然在同一个类中可以实现任意数量的接口,但 Java 编程语言只允许一个类有一个父类。
同时,某些程序员避免从 Thead 类导出,因为它强加了类层次。
对于这种情况,就要 unnale 接口。
Runnale 接口 此接口只有一个函数,un(),此函数必须由实现了此接口的类实现。
但是,就运行这个类而论,其语义与前一个示例稍有不同。
我们可以用 unnale 接口改写前一个示例。
(不同的部分用黑体表示。
)
java如何实现文件上传和下载的功能
多线程在java的中主要是通过实现runnable接口来完成的。
一谈到多线程就会有同步互斥的问题,对于静态变量的处理也是一个难点。
还有就是同步方法的运用,得当与否直接关系到运行的效率问题。
如果你的工作对多线程有比较多的要求,建议你看看head first java中对多线程的描述,比较专业一点的还有本多线程编程,封面画了一只章鱼。
有兴趣的话可以看看。
如果你做BS开发提醒一下在servlet 中除了局部变量和request对象是线程安全带的,剩下的都不是,一定要切记!
Java怎么实现多线程?
1. 虚假的多线程 例1: pulic class TestThead { int i=0, j=0; pulic void go(int flag){ while(tue){ ty{ Thead.sleep(100); } catch(InteuptedException e){ System.out.pintln("Inteupted"); } if(flag==0) i++; System.out.pintln("i=" + i); } else{ j++; System.out.pintln("j=" + j); } } } pulic static void main(Sting[] ags){ new TestThead().go(0); new TestThead().go (1); }} 上面程序的运行结果为: i=1 i=2 i=3 。
。
。
结果将一直打印出I的值。
我们的意图是当在while循环中调用sleep()时,另一个线程就将起动,打印出j的值,但结果却并不是这样。
关于sleep()为什么不会出现我们预想的结果,在下面将讲到。
2. 实现多线程 通过继承class Thead或实现Runnale接口,我们可以实现多线程 2.1 通过继承class Thead实现多线程 class Thead中有两个最重要的函数un()和stat()。
1) un()函数必须进行覆写,把要在多个线程中并行处理的代码放到这个函数中。
2) 虽然un()函数实现了多个线程的并行处理,但我们不能直接调用un()函数,而是通过调用stat()函数来调用un()函数。
在调用stat()的时候,stat()函数会首先进行与多线程相关的初始化(这也是为什么不能直接调用un()函数的原因),然后再调用un()函数。
例2: pulic class TestThead extends Thead{ pivate static int theadCount = 0; pivate int theadNum = ++theadCount; pivate int i = 5; pulic void un(){ while(tue){ ty{ Thead.sleep(100); } catch(InteuptedException e){ System.out.pintln("Inteupted"); } System.out.pintln("Thead " + theadNum + " = " + i); if(--i==0) etun; } } pulic static void main(Sting[] ags){ fo(int i=0; i5; i++) new TestThead().stat(); }} 运行结果为: Thead 1 = 5 Thead 2 = 5 Thead 3 = 5 Thead 4 = 5 Thead 5 = 5 Thead 1 = 4 Thead 2 = 4 Thead 3 = 4 Thead 4 = 4 Thead 1 = 3 Thead 2 = 3 Thead 5 = 4 Thead 3 = 3 Thead 4 = 3 Thead 1 = 2 Thead 2 = 2 Thead 5 = 3 Thead 3 = 2 Thead 4 = 2 Thead 1 = 1 Thead 2 = 1 Thead 5 = 2 Thead 3 = 1 Thead 4 = 1 Thead 5 = 1 从结果可见,例2能实现多线程的并行处理。
Java如何实现多线程组的控制?
class NewThead extends Thead{ oolean suspendFlag; NewThead(Sting theadname, TheadGoup tgO){ supe(tgO, theadname); System.out.pintln("New thead: "+this); suspendFlag = false; stat(); } pulic void un(){ ty{ fo(int i=5;i0;i--){ System.out.pintln(getName()+": "+i); Thead.sleep(1000); synchonized(this){ while(suspendFlag){ wait(); } } } }catch(Exception e){ System.out.pintln("Exception in "+getName()); } System.out.pintln(getName()+"exiting."); } void mysuspend(){ suspendFlag = tue; } synchonized void myesume(){ suspendFlag = false; notify(); } }
java多线程这块一个小程序继承Thread类定义一个线程类,模
public class Cx implements Runnable{ public void run(){ String name = Thread.currentThread().getName(); if(name.equals("左手程序")){ for(int i=1;i System.out.println("我是左手程序"); try{ Thread.sleep(500); } catch(InterruptedException e){} } } else if(name.equals("主程序")){ for(int i=1;i System.out.println("我是主程序"); try{ Thread.sleep(500); } catch(InterruptedException e){} } } else if(name.equals("右手程序")){ for(int i=1;i System.out.println("我是右手程序"); try{ Thread.sleep(500); } catch(InterruptedException e){} } } } } public class Test { public static void main(String args[]){ Cx cx = new Cx(); Thread left,hand,right; left = new Thread(cx); hand = new Thread(cx); right = new Thread(cx); left.setName("左手程序"); hand.setName("主程序"); right.setName("右手程序"); left.start(); try{ Thread.sleep(2000); } catch(InterruptedException e){} hand.start(); try{ Thread.sleep(2000); } catch(InterruptedException e){} right.start(); } }
在Java 中多线程的实现方法有哪些,如何使用~~~~~~~~~~~~~~~~~~...
1、 认识Thread和RunnableJava中实现多线程有两种途径:继承Thread类或者实现Runnable接口。
Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。
在使用Thread的时候只需继承Thread,并且new一个实例出来,调用start()方法即可以启动一个线程。
Thread Test = new Thread();Test.start();在使用Runnable的时候需要先new一个实现Runnable的实例,之后启动Thread即可。
Test impelements Runnable;Test t = new Test();Thread test = new Thread(t);test.start();总结:Thread和Runnable是实现java多线程的2种方式,runable是接口,thread是类,建议使用runable实现java多线程,不管如何,最终都需要通过thread.start()来使线程处于可运行状态。
2、 认识Thread的start和run1) start:用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。
通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
2) run:run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
3、 线程状态说明线程状态从大的方面来说,可归结为:初始状态、可运行状态、不可运行状态和消亡状态,具体可细分为上图所示7个状态,说明如下:1) 线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,当我们new了thread实例后,线程就进入了初始状态;2) 当该对象调用了start()方法,就进入可运行状态;3) 进入可运行状态后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;4) 进入运行状态后case就比较多,大致有如下情形:·run()方法或main()方法结束后,线程就进入终止状态;·当线程调用了自身的sleep()方法或其他线程的join()方法,就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源)。
当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配时间片;·当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被锁牢(synchroniza,lock),将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入可运行状态,等待OS分配CPU时间片;·当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。
·当线程调用stop方法,即可使线程进入消亡状态,但是由于stop方法是不安全的,不鼓励使用,大家可以通过run方法里的条件变通实现线程的stop。
java模拟龟兔赛跑问题用多线程实现
毫秒"。
谁先到终点就结束程序 * ,并显示获胜方; new Thread(t); System.out.println(winnnerName+"胜利"); System; } } } @Override public void run(){ new Thread(new Rabbit_Run()).start(); new Thread(new Tortoise_Run());兔子休息中………………"); Thread.currentTimeMillis().out.println(".start();每秒跑5步 System.out.println("兔子已跑"+rabbit_walk+".Date;public class Test extends Thread{ private int tortoise_walk = 0; long temp_lastTime=System.println(".out;/ 终点 private volatile boolean hasWinner = false;/: TODO(乌龟奔跑线程) * @author guotingchao * @date 2012-3-6 上午10; System.out.println("所耗时间:"+(temp_lastTime-temp_actionTime)+"毫秒"); System.out.println("兔子="+t.rabbit_walk+" 乌龟="+t.tortoise_walk); }}//不知道兔子和乌龟的步长时间是否按每秒。
这里程序只考虑依次递增频率;/ 乌龟已跑长度存放变量 private int rabbit_walk = 0; //乌龟"!hasWinner) { if (rabbit_walk % 20 == 0 && (rabbit_walk ;乌龟休息中………………"); Thread.out.println(").sleep(500); } rabbit_walk=rabbit_walk+5import java.util;比赛开始:"+new Date(temp_actionTime)+".printStackTrace()。
) * @param @param args * @param @throws Exception 设定文件 * @author guotingchao * @return void 返回类型 * @throws */ public static void main(String[] args) throws Exception { long temp_actionTime=System.currentTimeMillis(); System;:"兔子"?"比赛结束:"+new Date(temp_lastTime)+"米"); } } catch (InterruptedException e) { e: Tortoise_Run * @Description.printStackTrace():20:45 * */ class Tortoise_Run implements Runnable { @Override public void run() { try { while (; System;** * @Title: main * @Description: TODO( * 赛程1000米,兔子跑5米,乌龟跑1米,兔子每20米休息500毫秒,乌龟每100米休息500毫秒;t; while(true){ if(t;毫秒".finish){ t: TODO(兔子奔跑线程) * @date 2012-3-6 上午10:25;兔子每20米休息500毫秒 System.rabbit_walk>=t.println(").tortoise_walk>=t; //+tortoise_walk+"米".out.sleep(500); } tortoise_walk++; Test t=new Test()!hasWinner) { if (tortoise_walk % 100 == 0 && (tortoise_walk != 0||tortoise_walk>=finish)) { /); } } catch (InterruptedException e) { e; } /.out.rabbit_walk!= 0||rabbit_walk>.start();/乌龟每100米休息500毫秒 System: Rabbit_Run * @Description; } } } /** * * @ClassName;乌龟已跑".println(".hasWinner=true; break; } } String winnnerName=t.tortoise_walk>:10 * @author guotingchao */ class Rabbit_Run implements Runnable { @Override public void run() { try { while (; 兔子已跑长度存放变量 private int finish = 1000; /.finish||t;/ 胜利者诞生 /** * * @ClassName;=finish)) { // /