欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程小结

程序员文章站 2024-01-29 19:33:10
...
[size=medium][b]一、程序、进程、线程[/b][/size]
[size=medium]程序:静态的代码
进程:程序运行的过程
线程:比进程更小的执行单位,多线程给人一种多个事件同时发生的感觉(其实这是错觉)。[/size]
[size=medium][b]二、实现多线程常用的方法[/b][/size]
[size=medium]1、继承Thread 2、实现Runnable接口
无论使用这两种方法中的哪个,都要重写(或实现)run()方法,目的是规定线程的具体操作。
而调用线程具体操作时是要调用start()方法,并不是run()方法。
通过继承Thread实现多线程时,可以直接用Thread对象调用start()方法;
通过实现Runnable接口实现多线程时,仍然要用到Thread类
如下,ThreadTest和RunnableTest两个类中重写的run()方法的具体操作一样,一下两种实现多线程的方式得到的结果是一样的[/size]
public static void main(String[] args){
ThreadTest thread1 = new ThreadTest();
thread1.setName("thread1");
thread1.start();
ThreadTest thread2 = new ThreadTest();
thread2.setName("thread2");
thread2.start();
}

public static void main(String[] args) {
RunnableTest runnable1 = new RunnableTest();
Thread thread1 = new Thread(runnable1);
thread1.setName("thread1");
thread1.start();
RunnableTest runnable2 = new RunnableTest();
Thread thread2= new Thread(runnable2);
thread2.setName("thread2");
thread2.start();
}

[size=medium][b]三、多线程与并行[/b][/size]
[size=medium]多线程即为多个进程共享资源,多个线程排队等候使用CPU,但因为线程间转换的时间很短,所以像是多个线程并列独自运行。
并行则是有多个CPU,由少于CPU个数的多个进程使用,此时是多个进程真正意义上的同时进行。
比如一个人左右手都能写字,如果先用右手写一会儿,再用左手写,这样两手交替着写的话,就叫多线程;而如果两只手同时下笔,左手画圆,右手画方,这就是并行。[/size]
[size=medium][b]四、多线程应用[/b][/size]
[size=medium]1.弹球
功能介绍:通过点击按钮,添加小球、使指定小球停止、删除,同时可以直接单击小球使其停止,双击小球进行删除。
[img]http://dl2.iteye.com/upload/attachment/0087/2957/bf84cebe-1995-3cc8-9eac-9b138ee35701.jpg[/img]
在实现这个弹球程序的过程中,我遇到过以下问题,想和大家分享一下:
a.彩色背景下的重绘
如果背景是纯色的,要实现小球移动会比较容易,只要每次用一个背景色的小球填充原来的位置即可,可是如果背景是副图片的画,自然不能再画一个小圆来填充了。对此,我从老师那里学到了一个新的类BufferedImage,可以把每个时刻窗体显示出的画面都保存在BufferedImage中,再以整幅图片的形式在窗体中重绘出来。[/size]
public void run(){
while(true){
try {
Thread.sleep(100);
BufferedImage bi = new BufferedImage(800,620,BufferedImage.TYPE_3BYTE_BGR);
Graphics g=bi.getGraphics();
ImageIcon image = new ImageIcon("images/threadBg.jpg");
g.drawImage(image.getImage(), 0, 0, null);
for(int i=0; i<threadList.size();i++){
BallThread thread = threadList.get(i);
thread.drawBall(g);
}
panel.getGraphics().drawImage(bi, 0, 0, panel.getWidth(), panel.getHeight(), null);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

[size=medium]b.小球碰撞后方向的改变,首先是要计算小球圆形间的距离,一旦小于等于它们半径的和,就开始改变方向。但这个方向改变时,应该从相撞时的上一个位置开始就改变方向,否则两个小球就会不停地来回晃动,虽一直打架,却始终都分不开。[/size]
/**
* if the balls meet,change their state
* @param dd
* @return
*/
public boolean collision(){
for(BallThread com : threadList){
if(this.getId() == com.getId())
continue;
int x_oth = com.getX();
int y_oth = com.getY();
int r_oth = com.getR();
int distance=(int) Math.hypot((double)Math.abs(x_oth+r_oth-x-r),(double) Math.abs(y_oth+r_oth-y-r));
if(distance<=r_oth+r && distance>0){
return true;
}
}
return false;
}

/**
* change the ball's direction and speed according to its position
*/
public void move(){
if(xdirection==RIGHT){
x+=xspeed;
if(collision()){
this.x_convert();
x-=xspeed;
}
}else if(xdirection==LEFT){
x-=xspeed;
if(collision()){
this.x_convert();
x+=xspeed;
}
}
if(ydirection==UP){
y-=yspeed;
if(collision()){
this.y_convert();
y+=yspeed;
}
}else if(ydirection==DOWN){
y+=yspeed;
if(collision()){
this.y_convert();
y-=yspeed;
}
}
}

[size=medium]c.小球的停止和删除,通过设置布尔型的属性,来控制线程的运行[/size]
public void run(){
initCharacter();
while(true){
try {
sleep(100);
if(delete){//删除
return;
}
if(pause){//停止
System.out.println("pause="+this.pause);
continue;
}
move();//运动
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

[size=medium]2.端口扫描器
通过设置不同数目的线程共同检查端口是否可用,以比较搜索的快慢。搜索的基本方法是看Socket socket = new Socket(ip,i);是否抛出异常,如果抛出异常,则该端口i不能用。[/size]

[img]http://dl2.iteye.com/upload/attachment/0087/2959/a4d45df4-ab9c-3e65-9976-e360dbd27811.jpg[/img]