线程和进程简述
进程
A:线程和进程
要想说线程,首先必须得聊聊进程,因为线程是依赖于进程存在的。
B:进程概述
什么是进程呢?通过任务管理器我们就可以看到进程的存在。
概念:进程就是正在运行的程序,是系统进行资源分配和调用的独立单位。
每一个进程都有它自己的内存空间和系统资源。
C:多进程的意义
单进程计算机只能做一件事情。而我们现在的计算机都可以一边玩游戏(游戏进程),一边听音乐(音乐进程),
所以我们常见的操作系统都是多进程操作系统。比如:Windows,Mac和Linux等,能在同一个时间段内执行多个任务。
对于单核计算机来讲,游戏进程和音乐进程是同时运行的吗?不是。
因为CPU在某个时间点上只能做一件事情,计算机是在游戏进程和音乐进程间做着频繁切换,且切换速度很快,
所以,我们感觉游戏和音乐在同时进行,其实并不是同时执行的。多进程的作用不是提高执行速度,而是提高CPU的使用率。
线程
A:什么是线程
在一个进程内部又可以执行多个任务,而这每一个任务我们就可以看成是一个线程。是程序使用CPU的基本单位。所以,进程是拥有资源的基本单位, 线程是CPU调度的基本单位。
B:多线程有什么意义呢?
多线程的作用不是提高执行速度,而是为了提高应用程序的使用率。
那么怎么理解这个问题呢?
我们程序在运行的使用,都是在抢CPU的时间片(执行权),如果是多线程的程序,那么在抢到
CPU的执行权的概率应该比较单线程程序抢到的概率要大.那么也就是说,CPU在多线程程序
中执行的时间要比单线程多,所以就提高了程序的使用率.但是即使是多线程程序,那么他们
中的哪个线程能抢占到CPU的资源呢,这个是不确定的,所以多线程具有随机性.
C:大家注意两个词汇的区别:并行和并发。
前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
后者是物理上同时发生,指在某一个时间点同时运行多个程序。
简单来说,线程就是最基本的路线,比如国道,高速,小路,航线,轮渡,而进程就是方式:开车,坐飞机,做轮船,所以线程必须依赖于进程。 多线程的意义:提高CPU的利用率,就像开车,坐飞机,轮渡都在运输,把CPU的处理能力都调动起来。
线程创造方式一
public class MyThread extends Thread{
public MyThread(String la) {
super(la);
}
@Override
public void run() {
String name = this.getName();
for (int i = 0; i < 10000; i++) {
System.out.println(name+i);
}
}
}
创造一个类,继承Thread,并且必须重写run方法;
public class MyTest {
public static void main(String[] args) throws InterruptedException {
//run();
//Thread.currentThread().setDaemon(true);
MyThread haha= new MyThread("haha");
MyThread lalala = new MyThread("lalala");
haha.setDaemon(true); //守护线程,主线程结后,子线程自动结束
lalala.setDaemon(true);
haha.start();
haha.sleep(5000); //该线程睡眠5秒
haha.join(); //线程有序进行,不会抢时间片
lalala.start();
lalala.sleep(5000);
lalala.interrupt(); // 唤醒睡眠中的线程
lalala.join();
//haha.setDaemon(true);
// Thread thread = Thread.currentThread();//获取当前线程
// thread.setName("Max");
// String name = thread.getName();
//System.out.println(name);
}
}
线程创造方式二
public class MyRunnable implements Runnable{
static int piao=100;
Object obj= new Object();
@Override
public void run() {
while (true){
synchronized (obj){//执行代码块,防止多个线程同时抢到某个资源
if(piao>=1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖出第"+piao--+"张票");
}
}
}
}
}
创建一个类,该类实现一个runnable接口,并且必须重写run方法
public class MyTest {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable);
Thread thread2 = new Thread(myRunnable);
Thread thread3 = new Thread(myRunnable);
thread1.setName("窗口一");
thread2.setName("窗口二");
thread3.setName("窗口三");
thread1.start();
thread2.start();
thread3.start();
}
}
实现了三个窗口卖100张票。
线程创建方式三
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("线程执行了");
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
return sum;
}
}
创建一个类,并且让该类实现Callable接口,必须重写call方法,注意这里重写的是call方法,这是一个有返回值的线程实现方法,其他两种方式没有返回值,利用该返回值信息,我们可以做一些其他应用,这里返回了1-100的和。
public class MyTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<Integer>(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
Integer integer = futureTask.get();//获取返回值
System.out.println(integer);
}
}