**
多线程基础(一)
**
1、什么是线程什么是进程
进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源
线程:CPU调度的最小单位,必须依赖进程而存在。
(个人理解)
假设操作系统是一场运动会
计算机的硬件就如同场地(足球场,篮球场、跑道)
进程就像是一场运动比赛,
线程就是参加某场比赛的人,
操作系统和进程线程的一些基本概念描述如下:
(1)资源(端口)占用
不同的比赛都可以运用不同的场地(这其中互不干扰,如同硬件中的声卡、显卡之类的毫不干扰),假设1000米比赛正在进行,占用了跑道,这个时候需要进行400米跑步,其中一个运动占用场地,400米跑不动,就说被占掉了,也就是常说的资源被占用(进程(端口)被占用),
(2)单线程
而线程就是跑1000米的人,在最开始的时候,跑一个人,这就是单线程,
(3)多线程
后来大家发现这样子太占用比赛时间,于是新增3条跑道,这个时候一共四条跑道,在计算机里边就是4核,也可以多新增7条,就是8核(可以按照一定规则新增),我们可以允许四个人同时跑,这样子在计算机里边就算是多线程了,
(4)线程上下文切换
四个人跑就是4个线程同时进行,但是另一个问题出现了,还是太慢的情况,假如八个人参赛,分两次很耗时,如果跑的人有快有慢,我们可以让八个人同时跑,如果有人来了,让另外一个人让开,等一下,让过来的人跑过去了在继续跑,就是所谓的线程上下文切换,
(5)线程安全问题
当然了还存在很多问题,前边的人跑,后边的人跑得快,两人同时使用一条跑道(线程公用同一个资源),撞上去了,猪撞树上了,这就是多线程引发的线程安全问题(不同线程抢夺同一个资源的时候(不同的人,跑同一个跑道的时候)),
(6)多线程锁的作用
这个时候,也需要处理,跑步的人做一个栅栏(锁),只有我停下来,把栅栏移开后边的人才能跑这条跑道(其余的线程使用资源),后边的人来了之后继续放一个栅栏(线程加锁),继续这个过程,当然了,在一定情况下,由于加了栅栏,别人跑,你就只能做别的,如果强行没事,就只能继续等着,所以使用栅栏在赛道上,是很耗费时间的,这个栅栏可以加在开始,也可以加在中途合适的位置(锁的位置,方法,对象,代码块),栅栏拦住的越大(多线程中锁加的范围越大),耗的时间就会越多。
2、CPU核心数和线程数的关系
核心数:线程数=1:1
使用了超线程技术后—> 1:2
3、并行和并发的含义
并行:同一时刻,可以同时处理事情的能力(火车站售票窗口最多可以同时给几个人售票,)
并发:与单位时间相关,在单位时间内可以处理事情的能力(一个小时内,火车站最多可以给多少人售票)
4、高并发的优点和缺点
优点:在一定程度上快,因为就像跑道一样,为了让下一个人能好好的跑,前边的人需要让路,必然耗费时间,开栅栏(释放锁)关闭栅栏(加锁)更是耗费时间,但是毕竟可以让很多人同时跑,所以如果是长跑肯定不错,如果是20米短跑,这样子肯定不如一个一个来
缺点:优点有说,
(2)如果两个人用一个跑道,同时到了栅栏,A你先跑,B你先跑,这就是乐观锁,再来向栅栏冲几次(总有不同时到来的机会),很好解决(但是更耗费时间)
(3)A到了,栅栏B锁着,A说你给我开,B说你让开,我给你开,A说你开了我给你让。。。。。。。。。。就这么耗下去,死锁(更是耗费时间,而且不太好找出问题)
当然了还有别的缺点,但是因为可以让很多人一起跑步,这一个巨大的优点,我们都只会解决这些缺点,不知道未来会不会将这些缺点解决掉。
多线程启动方式(三种):
(1)继承Thread类
(2)实现Runnable接口
(3)实现Callable接口
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class NewThread {
//继承Thread
public static class MyThread extends Thread{
public void run(){
System.out.println("This is a thread");
}
}
//实现Runnable接口
public static class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("This is a runnableThread");
}
}
//实现Callable<R>接口
public static class MyCallable implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("This is a CallableThread");
return "sss";
}
}
public static void main(String[] args){
MyThread thread1 = new MyThread();
thread1.start();
thread1.interrupt();//中断
thread1.isInterrupted();//该线程是否中断
Thread.interrupted();//判断以后会将中断标志位置为false
MyRunnable thread2 = new MyRunnable();
new Thread(thread2).start();
MyCallable myCallable = new MyCallable();
FutureTask<String> task = new FutureTask<String>(myCallable);
new Thread(task).start();
try {
String temp = task.get();
System.out.println(temp);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是我得一些粗浅看法,希望有前辈和同行能够为我指出不足之处,万分感谢。
我得联系方式:QQ228769058