
在Java语言产生前 传统的程序设计语言的程序同一时刻只能单任务 *** 作 效率非常低 例如程序往往在接收数据输入时发生阻塞 只有等到程序获得数据后才能继续运行 随着Internet的迅猛发展 这种状况越来越不能让人们忍受 如果网络接收数据阻塞 后台程序就处于等待状态而不继续任何 *** 作 而这种阻塞是经常会碰到的 此时CPU资源被白白的闲置起来 如果在后台程序中能够同时处理多个任务 该多好啊!应Internet技术而生的Java语言解决了这个问题 多线程程序是Java语言的一个很重要的特点 在一个Java程序中 我们可以同时并行运行多个相对独立的线程 例如 我们如果创建一个线程来进行数据输入输出 而创建另一个线程在后台进行其它的数据处理 如果输入输出线程在接收数据时阻塞 而处理数据的线程仍然在运行 多线程程序设计大大提高了程序执行效率和处理能力
线程的创建
我们知道Java是面向对象的程序语言 用Java进行程序设计就是设计和使用类 Java为我们提供了线程类Thread来创建线程 创建线程与创建普通的类的对象的 *** 作是一样的 而线程就是Thread类或其子类的实例对象 下面是一个创建启动一个线程的语句
Thread thread =new Thread(); file://声明一个对象实例 即创建一个线程
Thread run(); file://用Thread类中的run()方法启动线程
从这个例子 我们可以通过Thread()构造方法创建一个线程 并启动该线程 事实上 启动线程 也就是启动线程的run()方法 而Thread类中的run()方法没有任何 *** 作语句 所以这个线程没有任何 *** 作 要使线程实现预定功能 必须定义自己的run()方法 Java中通常有两种方式定义run()方法
通过定义一个Thread类的子类 在该子类中重写run()方法 Thread子类的实例对象就是一个线程 显然 该线程有我们自己设计的线程体run()方法 启动线程就启动了子类中重写的run()方法
通过Runnable接口 在该接口中定义run()方法的接口 所谓接口跟类非常类似 主要用来实现特殊功能 如复杂关系的多重继承功能 在此 我们定义一个实现Runnable() 接口的类 在该类中定义自己的run()方法 然后以该类的实例对象为参数调用Thread类的构造方法来创建一个线程
线程被实际创建后处于待命状态 激活(启动)线程就是启动线程的run()方法 这是通过调用线程的start()方法来实现的
下面一个例子实践了如何通过上述两种方法创建线程并启动它们
// 通过Thread类的子类创建的线程 class thread extends Thread { file://自定义线程的run()方法 public void run() { System out println( Thread is running… ); } } file://通过Runnable接口创建的另外一个线程 class thread implements Runnable { file://自定义线程的run()方法 public void run() { System out println( Thread is running… ); } } file://程序的主类 class Multi_Thread file://声明主类 { plubic static void mail(String args[]) file://声明主方法 { thread threadone=new thread (); file://用Thread类的子类创建线程 Thread threado=new Thread(new thread ()); file://用Runnable接口类的对象创建线程 threadone start(); threado start(); file://strat()方法启动线程 } }
运行该程序就可以看出 线程threadone和threado交替占用CPU 处于并行运行状态 可以看出 启动线程的run()方法是通过调用线程的start()方法来实现的(见上例中主类) 调用start()方法启动线程的run()方法不同于一般的调用方法 调用一般方法时 必须等到一般方法执行完毕才能够返回start()方法 而启动线程的run()方法后 start()告诉系统该线程准备就绪可以启动run()方法后 就返回start()方法执行调用start()方法语句下面的语句 这时run()方法可能还在运行 这样 线程的启动和运行并行进行 实现了多任务 *** 作
线程的优先级
对于多线程程序 每个线程的重要程度是不尽相同 如多个线程在等待获得CPU时间时 往往我们需要优先级高的线程优先抢占到CPU时间得以执行 又如多个线程交替执行时 优先级决定了级别高的线程得到CPU的次数多一些且时间多长一些 这样 高优先级的线程处理的任务效率就高一些
Java中线程的优先级从低到高以整数 ~ 表示 共分为 级 设置优先级是通过调用线程对象的setPriority()方法 如上例中 设置优先级的语句为
thread threadone=new thread (); file://用Thread类的子类创建线程
Thread threado=new Thread(new thread ()); file://用Runnable接口类的对象创建线程
threadone setPriority( ); file://设置threadone的优先级
threado setPriority( ); file://设置threado的优先级
threadone start(); threado start(); file://strat()方法启动线程
这样 线程threadone将会优先于线程threado执行 并将占有更多的CPU时间 该例中 优先级设置放在线程启动前 也可以在启动后进行设置 以满足不同的优先级需求
线程的(同步)控制
一个Java程序的多线程之间可以共享数据 当线程以异步方式访问共享数据时 有时候是不安全的或者不和逻辑的 比如 同一时刻一个线程在读取数据 另外一个线程在处理数据 当处理数据的线程没有等到读取数据的线程读取完毕就去处理数据 必然得到错误的处理结果 这和我们前面提到的读取数据和处理数据并行多任务并不矛盾 这儿指的是处理数据的线程不能处理当前还没有读取结束的数据 但是可以处理其它的数据
如果我们采用多线程同步控制机制 等到第一个线程读取完数据 第二个线程才能处理该数据 就会避免错误 可见 线程同步是多线程编程的一个相当重要的技术
在讲线程的同步控制前我们需要交代如下概念
用Java关键字synchonized同步对共享数据 *** 作的方法
在一个对象中 用synchonized声明的方法为同步方法 Java中有一个同步模型 监视器 负责管理线程对对象中的同步方法的访问 它的原理是 赋予该对象唯一一把 钥匙 当多个线程进入对象 只有取得该对象钥匙的线程才可以访问同步方法 其它线程在该对象中等待 直到该线程用wait()方法放弃这把钥匙 其它等待的线程抢占该钥匙 抢占到钥匙的线程后才可得以执行 而没有取得钥匙的线程仍被阻塞在该对象中等待
file://声明同步的一种方式 将方法声明同步
class store {public synchonized void store_in(){… }public synchonized void store_out(){ … }}
利用wait() notify()及notifyAll()方法发送消息实现线程间的相互联系
Java程序中多个线程通过消息来实现互动联系的 这几种方法实现了线程间的消息发送 例如定义一个对象的synchonized 方法 同一时刻只能够有一个线程访问该对象中的同步方法 其它线程被阻塞 通常可以用notify()或notifyAll()方法唤醒其它一个或所有线程 而使用wait()方法来使该线程处于阻塞状态 等待其它的线程用notify()唤醒
一个实际的例子就是生产和销售 生产单元将产品生产出来放在仓库中 销售单元则从仓库中提走产品 在这个过程中 销售单元必须在仓库中有产品时才能提货 如果仓库中没有产品 则销售单元必须等待
程序中 假如我们定义一个仓库类store 该类的实例对象就相当于仓库 在store类中定义两个成员方法 store_in() 用来模拟产品制造者往仓库中添加产品 strore_out()方法则用来模拟销售者从仓库中取走产品 然后定义两个线程类 customer类 其中的run()方法通过调用仓库类中的store_out()从仓库中取走产品 模拟销售者 另外一个线程类producer中的run()方法通过调用仓库类中的store_in()方法向仓库添加产品 模拟产品制造者 在主类中创建并启动线程 实现向仓库中添加产品或取走产品
如果仓库类中的store_in() 和store_out()方法不声明同步 这就是个一般的多线程 我们知道 一个程序中的多线程是交替执行的 运行也是无序的 这样 就可能存在这样的问题
仓库中没有产品了 销售者还在不断光顾 而且还不停的在 取 产品 这在现实中是不可思义的 在程序中就表现为负值 如果将仓库类中的stroe_in()和store_out()方法声明同步 如上例所示 就控制了同一时刻只能有一个线程访问仓库对象中的同步方法 即一个生产类线程访问被声明为同步的store_in()方法时 其它线程将不能够访问对象中的store_out()同步方法 当然也不能访问store_in()方法 必须等到该线程调用wait()方法放弃钥匙 其它线程才有机会访问同步方法
lishixinzhi/Article/program/Java/gj/201311/27301
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java是一个强类型语言,它允许扩展编译时检查潜在类型不匹配问题的功能。Java要求显式的方法声明,它不支持C风格的隐式声明。
Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
Java的特点:
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点;下面我们来具体介绍一下:
1、简单性
Java看起来设计得很像C++,但是为了使语言小和容易熟悉,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的。例如,Java不支持go to语句,代之以提供break和continue语句以及异常处理。Java还剔除了C++的 *** 作符过载(overload)和多继承特征,并且不使用主文件,免去了预处理程序。因为Java没有结构,数组和串都是对象,所以不需要指针。Java能够自动处理对象的引用和间接引用,实现自动的无用单元收集,使用户不必为存储管理问题烦恼,能更多的时间和精力花在研发上。
2、面向对象
Java语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。Java语言全面支持动态绑定,而C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
3、分布性
Java设计成支持在网络上应用,它是分布式语言。Java既支持各种层次的网络连接,又以Socket类支持可靠的流(stream)网络连接,所以用户可以产生分布式的客户机和服务器。
网络变成软件应用的分布运载工具。Java程序只要编写一次,就可到处运行。
4、编译和解释性
Java编译程序生成字节码(byte-code),而不是通常的机器码。Java字节码提供对体系结构中性的目标文件格式,代码设计成可有效地传送程序到多个平台。Java程序可以在任何实现了Java解释程序和运行系统(run-time system)的系统上运行。
在一个解释性的环境中,程序开发的标准“链接”阶段大大消失了。如果说Java还有一个链接阶段,它只是把新类装进环境的过程,它是增量式的、轻量级的过程。因此,Java支持快速原型和容易试验,它将导致快速程序开发。这是一个与传统的、耗时的“编译、链接和测试”形成鲜明对比的精巧的开发过程。
5、稳健性
Java原来是用作编写消费类家用电子产品软件的语言,所以它是被设计成写高可靠和稳健软件的。Java消除了某些编程错误,使得用它写可靠软件相当容易。
Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。Java的安全检查机制使得Java更具健壮性。
6、安全性
Java的存储分配模型是它防御恶意代码的主要方法之一。Java没有指针,所以程序员不能得到隐蔽起来的内幕和伪造指针去指向存储器。更重要的是,Java编译程序不处理存储安排决策,所以程序员不能通过查看声明去猜测类的实际存储安排。编译的Java代码中的存储引用在运行时由Java解释程序决定实际存储地址。
Java运行系统使用字节码验证过程来保证装载到网络上的代码不违背任何Java语言限制。这个安全机制部分包括类如何从网上装载。例如,装载的类是放在分开的名字空间而不是局部类,预防恶意的小应用程序用它自己的版本来代替标准Java类。
7、可移植性
Java使得语言声明不依赖于实现的方面。例如,Java显式说明每个基本数据类型的大小和它的运算行为(这些数据类型由Java语法描述)。
Java环境本身对新的硬件平台和 *** 作系统是可移植的。Java编译程序也用Java编写,而Java运行系统用ANSIC语言编写。
8、高性能
Java是一种先编译后解释的语言,所以它不如全编译性语言快。但是有些情况下性能是很要紧的,为了支持这些情况,Java设计者制作了“及时”编译程序,它能在运行时把Java字节码翻译成特定CPU(中央处理器)的机器代码,也就是实现全编译了。
Java字节码格式设计时考虑到这些“及时”编译程序的需要,所以生成机器代码的过程相当简单,它能产生相当好的代码。
9、多线程
在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。通常有两种方法来创建线程:
1)、使用型构为Thread(Runnable)的构造子类将一个实现了Runnable接口的对象包装成一个线程,
2)、从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。
10、动态性
Java语言的设计目标之一是适应于动态变化的环境。Java程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
11、平台独立性
Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后可以在实现这个Java平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
1 PATH环境变量。
作用是指定命令搜索路径,在命令行下面执行命令如javac编译java程序时,它会到PATH变量所指定的路径中查找看是否能找到相应的命令程序。我们需要把jdk安装目录下的bin目录增加到现有的PATH变量中,bin目录中包含经常要用到的可执行文件如javac/java/javadoc等待,设置好PATH变量后,就可以在任何目录下执行javac/java等工具了。
CLASSPATH环境变量。
作用是指定类搜索路径,要使用已经编写好的类,前提当然是能够找到它们了,JVM就是通过CLASSPATH来寻找类的。我们需要把jdk安装目录下的lib子目录中的dtjar和toolsjar设置到CLASSPATH中,当然,当前目录“”也必须加入到该变量中。
2、public class Test {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
int sum=0;//设定一个变量,求和的值
for(int i=1;i<=100;i++){
sum=sum+i;
}
Systemoutprintln("1+2+3++100的和:"+sum);
}
}
3、import javautilArrays;
public class Test {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
int str[]={1,3,9,5,4,8,2};
Arrayssort(str);
Systemoutprintln("数组中最大数:"+str[strlength-1]);
}
}
4、public class Test {
/
@param args
/
public static void main(String[] args) {
// TODO Auto-generated method stub
String str="abcjavatxt";//定义一个变量设置文件名称
Systemoutprintln(strsubstring(strlastIndexOf("")+1));
}
}
5、public class Student {
private String name;//姓名
private int age;//年龄
private double score;//成绩
public Student(String name,int age,double score){
thisname=name;
thisage=age;
thisscore=score;
}
public String getName() {
return name;
}
public void setName(String name) {
thisname = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
thisage = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
thisscore = score;
}
}
6、我就不贴代码了。你自己创建借个对象。然后把五个对象的成绩放在一个数组中,直接调用Arrayssort(数组名) 这个方法排序输出就ok了。
7、方法:可以使用文件流来读写。楼主可根据文件的类型选择是字节流还是字符流来实现。如果楼主还需要,可以把代码写出来
8、TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我们这里只做简单、形象的介绍,你只要做到能够理解这个过程即可。我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用TCP协议传输数据。
面向非连接的UDP协议
“面向非连接”就是在正式通信前不必与对方先建立连接,不管对方状态就直接发送。这与现在风行的手机短信非常相似:你在发短信的时候,只需要输入对方手机号就OK了。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!
UDP适用于一次只传送少量数据、对可靠性要求不高的应用环境。比如,我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。例如,在默认状态下,一次“ping” *** 作发送4个数据包(如图2所示)。大家可以看到,发送的数据包数量是4包,收到的也是4包(因为对方主机收到后会发回一个确认收到的数据包)。这充分说明了UDP协议是面向非连接的协议,没有建立连接的过程。正因为UDP协议没有连接的过程,所以它的通信效果高;但也正因为如此,它的可靠性不如TCP协议高。QQ就使用UDP发消息,因此有时会出现收不到消息的情况。
TCP协议和UDP协议各有所长、各有所短,适用于不同要求的通信环境。
9、<form id="register" name="register" method="post" action="">
<table width="380" border="0">
<tr>
<td width="93" height="37">用户名:</td>
<td width="271">
<input type="text" name="username" id="username" />
</td>
</tr>
<tr>
<td height="30">密码:</td>
<td><input type="password" name="pwd" id="pwd" /></td>
</tr>
<tr>
<td height="26">确认密码:</td>
<td><input type="password" name="confirmpwd" id="confirmpwd" /></td>
</tr>
<tr>
<td height="33">性别:</td>
<td>
<input type="radio" name="sex" value="女" />
男
<input type="radio" name="sex" value="男" />
女</td>
</tr>
<tr>
<td>城市:</td>
<td>
<select name="city" id="city">
<option value="" selected="selected"></option>
<option value="深圳市">深圳市</option>
<option value="上海市">上海市</option>
</select>
</td>
</tr>
<tr>
<td>兴趣爱好:</td>
<td><label>
<input type="checkbox" name="hobby" id="mountain" value="mountain" />
爬山
<input type="checkbox" name="hobby" id="basketball" value="basketball" />
篮球
<input type="checkbox" name="hobby" id="swimming" value="swimming" />
游泳</label></td>
</tr>
<tr>
<td>简介:</td>
<td>
<textarea name="introduce" cols="30" id="introduce" rows="3"></textarea>
</td>
</tr>
<tr>
<td> </td>
<td><label>
<input type="button" name="Submit" value="提交" onclick="check()"/>
</label></td>
</tr>
</table>
</form>
10、我给你写个js,你在代码中调用这个方法
<script language="javascript" type="text/javascript">
function check(){
//判断用户名
var username=documentgetElementById("username")value;
//定义正则表达式,用户名必须是字母数字或下划线, 不能以数字开头
var regex1=/^[A-Za-z_][0-9A-Za-z_]$/
var s=documentgetElementById("username")value;
alert(regex1test(s));
return;
if(regex1test(username)){
alert("用户名必须是字母数字或下划线, 不能以数字开头");
return;
}
//判断密码
//定义正则表达式,密码必须6-16位字母数字下划线
var regex2=/^[0-9A-Za-z_]{6,16}$/
var pwd=documentgetElementById("pwd")value;
if(regex2test(pwd)==false){
alert("密码必须6-16位字母数字下划线");
return;
}
//判断确认密码
var confirmpwd=documentgetElementById("confirmpwd");
if(pwdvalue!=confirmpwdvalue){
alert("两次密码输入不一致,请重新输入!");
return;
}
//判断性别、城市、爱好、简介
var sex=documentgetElementsByName("sex");
var city=documentgetElementById("city");
var hobby=documentgetElementsByName("hobby");
var introduce=documentgetElementById("introduce");
var t=0;
for(var i=0;i<sexlength;i++){
if(sex[i]checked==true){
t++;
}
}
if(t==0){
alert("请选择性别!");
return;
}
t=0;
for(var i=0;i<hobbylength;i++){
if(hobby[i]checked==true){
t++;
}
}
if(t==0){
alert("请选择爱好!");
return;
}
if(cityvalue==""){
alert("城市不能为空,请选择城市");
return;
}
if(introducevalue==""||introducevaluelength==0){
alert("个人简介不能为空");
return;
}
}
</script>
以上有不对的地方尽请指出,谢谢
以上就是关于Java多线程程序设计初步入门全部的内容,包括:Java多线程程序设计初步入门、JAVA语言介绍是什么、java基础知识等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)