进程和线程的区别进程是指在 *** 作系统中正在运行的一个应用程序,线程是指进程内独立执行某个任务的一个单元
一个进程中包含多个线程,线程是cpu调度的最小单位
多线程的概念进程与线程之间的区别:
进程 : 系统中的程序,一个进程之间可以包含1~n个线程,系统中资源分配的最小单位,每个进程都有自己的代码与数据空间,进程之间的切换开销较大
线程 : 程序中的顺序流,线程是cpu调度与执行的最小单位,多个线程之间共享进程的代码和数据空间,每一个线程都有自己的程序计数器运行栈,线程之间切换开销较小
线程的状态一个cpu同一时刻只能调度一个线程【但是cpu处理信息较快,可以在某一个时间段内,来回切换执行线程,所以这个概念叫做“多线程”】
创建线程的方式一个线程的状态可以分为:
新生状态 就绪状态 运行状态 阻塞状态 终止状态
详情请参考
创建线程方式1 代码Demo1:继承Thread,重写run方法 + start开启线程
2:实现Runnable接口,重写run方法 + start开启线程
3:实现Callable接口,重写call方法 + 线程池
//1:继承Thread public class Class001_Thread extends Thread{ //2:重写run方法 @Override public void run() { for(int i = 1;i<=20;i++){ System.out.println("一边喝水"); //Thread.sleep方法是线程休眠的意思,表示执行到这里,这个线程等待 1 毫秒,cpu重现调度线程去执行,有可能会调度别的线程,也有可能还调度当前的这个线程,此语句只是为了增加cpu调度别的线程的可能性 try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { //3:创建一个线程对象 Class001_Thread th = new Class001_Thread(); //4:调用线程对象的start方法,开启线程,cpu调用线程时会自动执行对象中的run方法 th.start(); for(int i = 1;i<=20;i++){ System.out.println("一边讲课...."); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }创建线程方式2 代码Demo
优点:接口多实现,类的单继承 方便实现资源共享
//1: 实现Runnable接口 public class Class002_Thread implements Runnable{ public static void main(String[] args) { //3:创建一个线程Thread对象,参数传递实现Runnable接口的对象 Thread th = new Thread(new Class002_Thread()); //4:调用线程对象的start方法,开启线程,cpu调用线程时会自动执行对象中的run方法 th.start(); for(int i = 1;i<=20;i++){ System.out.println("一边陪女朋友..."); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } //2:重写run方法 @Override public void run() { for(int i = 1;i<=20;i++){ System.out.println("一边打游戏..."); try { //线程休眠,cpu在次调度线程 Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }创建线程方式3 代码Demo
优点: call方法可以抛出异常,可以定义返回值,run方法不可以
//1:实现Callable接口,定义泛型 public class Class005_Callable implements Callable理解线程的资源共享和线程不安全情况{ //2:重新call方法,可以存在返回值 @Override public Integer call() { for(int i=1;i<=100;i++){ System.out.println(i); } return 1; } public static void main(String[] args) throws ExecutionException, InterruptedException { //3:创建一个线程池 创建一个固定大小2个线程的线程池--> 得到一个线程池提供的执行服务 ExecutorService server = Executors.newFixedThreadPool(2); //4:创建实现接口的对象 Class005_Callable racer = new Class005_Callable(); //5:将对象提交任务 【交由线程池管理运行,运行完毕后会有返回值】 submit(Callable task) Future result1 = server.submit(racer); Future result2 =server.submit(racer); //6:线程运行完毕后 得到结果 V get() Integer num1 = result1.get(); Integer num2 = result2.get(); System.out.println(num1); System.out.println(num2); //7:关闭服务 server.shutdown(); } }
== 用线程模拟三个人去买10张票==
public class CreatThread implements Runnable{ //一共10张票,模拟三个人同时去买 int ticket=10; public static void main(String[] args) { //创建一个对象,实现票数共享【如果创建三个对象,每个对象都会有自己的10张票】 CreatThread creatThread = new CreatThread(); //将创建的对象 当做参数交给Thread创建为三个线程去执行run方法 Thread t1 = new Thread(creatThread); Thread t2 = new Thread(creatThread); Thread t3 = new Thread(creatThread); t1.start(); t2.start(); t3.start(); } @Override public void run() { while (true){ //如果票数为0,表示退出 if(this.ticket<=0){ return; } //线程休眠,模拟买票花费的时间 try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } //打印买到的第几张票 System.out.println(Thread.currentThread().getName()+"购买了"+ (this.ticket--) +"张票"); } } }
三个线程执行一个对象中的数据,或者几个线程对于同一个数据 *** 作就是线程的资源共享
以上代码执行后,会发现,有同一张票卖给两个人,或者出现-1票的情况,这就是线程不安全
【线程不安全,是因为在线程执行代码到一半,并没有执行完方法体中代码时,cpu调度到另一个线程,比如a线程执行到判断票数的时候,不为0然后休眠,被cpu切换的b线程去执行,b线程买完了最后一张票,又切换到a线程去执行,继续上次执行的位置,就是买票,就会出现-1的情况】
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)