您的位置:首页 > 编程语言 > Java开发

进程与线程,java多线程的应用

2017-10-24 15:25 330 查看
一个程序至少有一个进程,一个进程至少有一个线程.

进程是程序在一个数据集合上的运行过程。它是系统进行资源分配和调度的一个独立单位。

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。

关于进程的使用,可以限制进程的数量,我觉得这是一个例子,比如有的程序它不允许你多客户端运行,如梦幻西游,它能限制你的客户端数量,可能就是从进程方面来做的,再比如LOL ,它只允许你运行一个客户端。

区别:

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

1) 简而言之,一个程序至少有一个进程,一个进程至少有一个线程.

2) 线程的划分尺度小于进程,使得多线程程序的并发性高。

3) 另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

4) 线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。

5) 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

为什么要用多线程?

由于Java采用的是单线程编程模型,因此在进行UI编程时要注意将耗时的操作放在子线程中进行,以避免阻塞主线程(在UI编程时,主线程即UI线程,用来处理用户的交互事件)

我们平时习惯的主函数就是一个线程,这个时候,如果我们在主函数中有一个非常耗时的操作,比如连接网络,连接数据库,或者大量的计算等等,在主函数的主线程中执行这些操作,带来的后果将是,在这些耗时操作完成之前,其他操作无法进行。比如在这个耗时操作之后有绘制UI的操作,这个时候,很可能会等上十几秒UI才能显示出来,这样的结果肯定会非常不好。

那么为了解决上述问题,我们就要使用多线程,在主线程外设置一个子线程,这样把耗时操作放在子线程中,主线程中运行一些简单的操作,如UI绘制等,这样就不会出现显示UI卡死的状况。

java中使用多线程 有两种方法: 继承Thread类, 实现Runable接口。

1

/**
* 因为输出10个数比较小,当你启动启动第二个线程时第一个线程已经运行完毕,
* 所以两次输出都是顺序输出,要么将i设置很大很大,要么让每次打印暂停一下
* @author Administrator
*
*/
public class ThreadTest {
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程A");
MyThread mt2 = new MyThread("线程B");
mt1.start();
mt2.start();
}
}

class MyThread extends Thread {
private String name;

public MyThread(String name) {
this.name = name;
}

public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + "运行,i=" + i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


2

/**
* 两个线程不一定谁先执行
* @author Administrator
*
*/

public class RunableTest {

public static void main(String[] args) {
System.out.println("主线程ID:" + Thread.currentThread().getId());
MyRunableThread runableThread1 = new MyRunableThread("线程1");
MyRunableThread runableThread2 = new MyRunableThread("线程2");
Thread thread1 = new Thread(runableThread1);
Thread thread2 = new Thread(runableThread2);
thread2.start();
thread1.run();
}

}

class MyRunableThread implements Runnable {
String name;

public MyRunableThread(String string) {
this.name = string;
}

@Override
public void run() {
System.out.println("子线程ID:" + name + ": " + Thread.currentThread().getId());

}

}




通过start()方法去启动线程。注意,不是调用run()方法启动线程,run方法中只是定义需要执行的任务,如果调用run方法,即相当于在主线程中执行run方法,跟普通的方法调用没有任何区别,此时并不会创建一个新的线程来执行定义的任务。

 1)thread1和thread2的线程ID不同,thread2和主线程ID相同,说明通过run方法调用并不会创建新的线程,而是在主线程中直接运行run方法,跟普通的方法调用没有任何区别;

 2)虽然thread1的start方法调用在thread2的run方法前面调用,但是先输出的是thread2的run方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 多线程 进程