1、程序:通过某种编程语言编写并实现一系列特定功能的静态代码。也就是说,我们编写好的代码,在没有运行之前,他就是一个程序。
2、进程:狭义来讲,是指正在运行的程序。一个正在运行的程序就是一个进程。广义来讲,进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。
举个类似的例子:当你从网上下载了一个QQ,你没有运行它,它就是一个程序。如果运行它,它就可以加载到内存空间,分配到cpu的资源。所以这时候,正在运行的QQ就是一个进程啦。
小提示:你可以通过同时按住Ctrl+Alt+delete组合键去打开任务管理,然后查看进程信息。你也可以通过在window页面的下边任务栏,右键点击任务管理器,查看进程信息。
二、多线程我们往往会看到这样子的情况,当你打开一个360安全卫士的时候,你不但可以进行“电脑清理”,还可以进行“全盘扫毒”、“一键修复”、“一键加速”等功能。但是细心的你,肯定会发现,它在进程里只运行着一个360安全卫士,但是他却干了好多好多事情。这个就是多线程。
所谓多线程就是进程的细化。多线程就是把操作系统中的这种并发执行机制原理运用在一个程序中,把一个程序划分为若干个子任务,多个子任务并发执行,每一个任务就是一个线程。这就是多线程程序。也就是说进程是线程的容器。
多线程可以在同一实现段实现多件事情,因此可以大大提高系统资源的利用率(CPU的利用率)。同时提高了用户体验和响应。
三、通过Thread实现多线程Java实现多线程是java.lang.Thread类。我们都知道放在lang包的类都是很常用的,可见Thread类也是一个非常常用的类。实现示例如下:
package cn.com.sise;
// 继承Thread类实现多线程
class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
}
}
public class MultiThread{
public static void main(String[] args) {
// 创建一个类的对象
ThreadDemo t = new ThreadDemo();
// 调用start方法开启多线程(ThreadDemo类的线程,为子线程)
t.start();
// 在main中的代码块,为主线程
for (int i=0;i < 10;i++){
System.out.println(i);
}
}
}
我们运行以后,看到下面的结果:
但是我们看不出来到底是那个线程先运行,所以我们给线程加个名字:(获取线程默认方法)
运行之后,我们可以看到以下结果:
我们明显的发现:两个循环执行结果是无序的(你可以通过多次执行结果来查看输出结果,直接观察)
这个时候,有些同学说,我能不能给线程取个中文名字?
答案是可以的,我们可以通过setName方法进行设置,具体设置的代码如下:
运行结果如下:多次运行,结果不一致
四、如果我运行好多次结果都一样咋整?对于不同的CPU,他在运行的时候,可能一直被某个线程抢到资源。因此,会导致这个线程全部运行完之后,再执行另一个线程。这个时候,我们可以进行手动睡眠的方法,使得“竞争不太那么激烈”。
这个时候我们可以通过sleep方法,具体代码如下:
package cn.com.sise;
// 继承Thread类实现多线程
class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MultiThread{
public static void main(String[] args) {
// 创建一个类的对象
ThreadDemo t = new ThreadDemo();
// 给t这个线程设置一个线程名
t.setName("子线程");
// 调用start方法开启多线程(ThreadDemo类的线程,为子线程)
t.start();
// 在main中的代码块,为主线程
for (int i=0;i < 10;i++){
// 使得当前线程睡眠一秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 给当前线程去一个线程名
Thread.currentThread().setName("主线程");
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
这时候运行的结果就非常清楚啦!
需要注意的是:在run方法中,sleep的异常只能用try...catch...来处理异常。
原因很简单:在Thread类中,run方法没有声明异常
而异常的规则是:子类所声明的异常,不能高于父类的异常。所以我们只能try...catch...
五、ThreadDemo类让他变成多个线程如果我们想让ThreadDemo里面的run方法变成多个线程。我们可以用如下的方式:
package cn.com.sise;
// 继承Thread类实现多线程
class ThreadDemo extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class MultiThread{
public static void main(String[] args) {
// 创建一个类的对象
ThreadDemo t1 = new ThreadDemo();
// 创建类的另外一个对象 t2
ThreadDemo t2 = new ThreadDemo();
// 给t1这个线程设置一个线程名
t1.setName("子线程1");
// 给t2这个线程设置一个线程名
t2.setName("子线程2");
// 调用start方法开启多线程(ThreadDemo类的线程,为子线程)
t1.start();
t2.start();
}
}
六、结尾
我们会发现,Java里面的继承是有局限性,那就是只能实现单继承,不能实现多继承。
但是我们会发现,点开Thread类源码,它竟然实现了Runable接口。
那是不是意味着Java的线程也可以通过实现Runable接口的方式来实现呢?那我们下个话题见哈!



