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

一个程序至少有一个进程,一个进程至少有一个线程.

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

线程是进程的一个实体,是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);
		thread1.start();
		thread2.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方法调用的相关信息,说明新线程创建的过程不会阻塞主线程的后续执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值