今天是学习Java的第三十天,感觉这一段日子的越往下学习,心态越着急,总想一下子什么都学透,但其实这是不可能的,好吧,沉下心来,一点的一点的慢慢刨~~
今天来聊聊进程和线程。
Windows就是一个多进程的系统,我们在一个时间段内是可以同时运行多个程序的,打开你的任务管理器看看就知道了~系统会为每一个进程分配资源(包括cpu和内存等),有些程序占得资源多,有些少。但其实在底层的话,一个时间点只能运行一个程序(因为cpu只有一个),多进程其实是一个假象,就是系统是通过运行一下这个进程,很短时间内又切换到另一个进程,就这样不断的切换,当然,切换的时间是非常非常短的,短的都让我们以为是同一时间在运行,这些都通过一个叫时间片的东西来实现。
线程是在进程的基础上进一步划分,一个进程还可以再划分多个线程,线程是比进程运行的更快的处理单元,占的资源也少。线程的存在离不开进程,进程消失后,线程一定会消失,反之则不然;
可以这样说:1. 进程是可以独立运行的一段程序,是系统进行资源分配和调度的一个基本单位,进程间相互独立;线程是进程的一个实体,是CPU调度和执行的基本单位,线程自己基本上不拥有系统资源,一个进程里的多线程可以共享进程内的资源;2 . 进程是在操作系统层面,线程是在程序运行层面。 那么在Java中如何实现多线程呢?
有三种方式,来看代码:
1. 继承Thread类;
Thread在Java中是一个支持多线程的类,任何一个类只要是继承了Thread类,那么就可以实现多线程的操作;缺点是因为Java是单继承多实现模式,如果一个类已经继承了其他类,则无法继承Thread类;
2. 实现Runnable接口
有两个好处,第一避免了单继承局限,第二是方便共享资源,同一份资源,多个代理访问;
3. 实现Callable接口
public class Rabbit extends Thread { //第一种方法:继承Thread类后重写run()方法;
@Override
public void run() {
for(int i = 0; i < 100; i ++) {
System.out.println("兔子跑跑跑" + i);
}
}
}
class Tor extends Thread {
@Override
public void run() {
for(int i = 0; i < 100; i ++) {
System.out.println("乌龟爬爬爬" + i);
}
}
}
public class TestDeme1 { //测试
public static void main(String[] args) {
Rabbit rab = new Rabbit();//创建子类对象;
Tor tor = new Tor();
rab.start();//调用start方法,不能直接调用run方法;
tor.start();
for(int i = 0; i < 100; i ++) {
System.out.println("我是main" + i);
}
}
}
第二种方法(推荐使用这种方法):
public class Web12306 implements Runnable {
private int num = 50;
@Override
public void run() {
while(true) {
if(num < 0) {
break;
}
System.out.println(Thread.currentThread().getName() + "抢到了:" + num--);
}
}
}
public class TestDeme1 {
public static void main(String[] args) {
//真实角色;
Web12306 web12306 = new Web12306();
//真实角色的三个代理
Thread t1 = new Thread(web12306, "黄牛甲");
//Thread类实现了Runnable接口,Runnable中只有一个run()方法(因为它是FuncitonalInterface);
//因此需要实例化Thread类对象然后调用start()方法,start()方法又去调用run()方法;
Thread t2 = new Thread(web12306, "黄牛乙");
Thread t3 = new Thread(web12306, "黄牛丙");
t1.start();//调用start方法;
t2.start();
t3.start();
}
}