黑马程序员 黑马程序员 Java的进程和线程

 ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

进程是指一个内存中运行的程序,每个进程都有自己的一块独立内存空间,一个进程可以有多个线程。比如在Window中运行一个xx.exe就是一个进程。

 

Java程序的进程里有几个线程:主线程、垃圾回收线程(后台线程)

 

线程指的是进程中的一个执行任务,一个进程可以执行多个线程,多个线程可以共享数据。

 

多进程:就是在操作系统中同时运行多个程序.......

多线程:在同一个进程中同时运行多个任务.......

 

一个进程至少有一个线程,为了提高效率,可以在一个进程中开启多个任务。

 

线程可以同时运行,但是通过程序运行的结果发现,虽然同时运行,但是每次结果都不一样。

因为多线程存在一个特性:随机性。

造成原因:CPU在瞬间不断切换去处理各个线程而导致的。

可以理解为多个线程在抢CPU资源。

 

线程具有许多传统进程所具有的特征,可以成为轻型进程。

而把传统的进程成为重型进程,它相当于只有一个线程在执行任务。在引入了线程的操作系统中,通常一个进程有若干个线程,至少有一个线程。

 

进程与线程的区别:

1、进程有独立的进程空间,进程中的数据存放空间,也就是堆空间与栈空间,它们是独立的。

2、线程的堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小,相互之间可以影响的。

 

创建线程的方法:

1、继承Thread

 

复制代码
 1 package xiao.li;
 2 
 3 public class 继承Thread类方式创建线程 {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         //Thread.currentThread()返回当前线程的对象
10         String name=Thread.currentThread().getName();//返回主线程名
11         //主线程与子线程是同时运行的。
12         for (int i = 1; i <=50; i++) {
13             System.out.println(name+"--->"+i);
14             if(i==20)
15             {
16                 //创建线程并启动线程
17                 new MyThread().start();//启动线程,其实就是调用run方法。
18                 //new MyThread().run();//如果这样写的话不是启动线程,而是在调用普通方法而已。
19             }
20         }
21     
22     }
23 }
24 /*
25  * 继承方式创建线程
26  */
27 class MyThread extends Thread
28 {
29     /*
30      * 覆写Thread类的run方法
31      */
32     public void run() {
33         for (int i = 1; i <=50; i++) {
34             /*
35              * this.getName()这个方法返回的是线程名:Thread-0。
36              * this.setName(String name)这个方法是设置线程名。
37              */
38             System.out.println(this.getName()+i);
39         }
40     }
41 }
复制代码

 

2、实现Runnable接口

 

复制代码
 1 package xiao.li;
 2 
 3 public class 实现Runnable接口方式创建线程 {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         //创建子线程对象
10         MyThread1 my = new MyThread1();
11         for (int i = 0; i < 50; i++) {
12             System.out.println(Thread.currentThread().getName()+"---->"+i);
13             if(i==25)
14             {            
15                 //创建线程,设置子线程名并启动线程
16                 new Thread(my,"leo").start();
17             }
18         }
19         
20     }
21 
22 }
23 /*
24  * 实现Runnable接口方式创建线程
25  */
26 class MyThread1 implements Runnable
27 {
28 
29     /*
30      * 实现run方法
31      */
32     public void run() {
33         //通过Thread.currentThread().getName()获取当前线程的名字,不能像继承Thread类那样直接调用getName()方法
34         for (int i = 0; i < 50; i++) {
35             System.out.println(Thread.currentThread().getName()+"--->"+i);
36         }
37     }
38 }
复制代码

 

这两种方法的运行结果:每运行一次结果都会不一样!

 

Thread卖票实例:

复制代码
 1 package xiao.li;
 2 
 3 public class 继承方式多线程卖票的例子 {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         new TicketThread("1号窗口").start();
11         new TicketThread("2号窗口").start();
12         new TicketThread("3号窗口").start();
13         /*
14          * 上面这种方法会重复卖票...
15          */
16     }
17 }
18 class TicketThread extends Thread
19 {
20     TicketThread(String name)
21     {
22         super(name);
23     }
24     int ticketNumber=10;
25     public void run() {
26         for (int i = 0; i < ticketNumber; i++) {
27             System.out.println(this.getName()+"卖出"+ticketNumber--+"号票");
28         }
29     }
30 }
复制代码

结果:

1号窗口卖出10号票
1号窗口卖出9号票
1号窗口卖出8号票
1号窗口卖出7号票
1号窗口卖出6号票
2号窗口卖出10号票
2号窗口卖出9号票
2号窗口卖出8号票
2号窗口卖出7号票
2号窗口卖出6号票
3号窗口卖出10号票
3号窗口卖出9号票
3号窗口卖出8号票
3号窗口卖出7号票
3号窗口卖出6号票

大家看,如果到火车站去买票,那么售票员就是这样买票的.....会引起冲突!既然1号窗口已经把10号座位卖出去了,为什么2号窗口还要继续卖呢?所以这样很不好......

Runnable:

复制代码
 1 package xiao.li;
 2 
 3 public class 实现接口方式多线程卖票例子 {
 4 
 5     /**
 6      * @param args
 7      */
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         MyTicket target = new MyTicket();
11         new Thread(target,"1号窗口").start();
12         new Thread(target,"2号窗口").start();
13         new Thread(target,"3号窗口").start();
14     }
15 }
16 class MyTicket implements Runnable
17 {
18     private int ticketNumber=10;
19     //实现run方法
20     public void run() {    
21         for (int i = 0; i <= 200; i++) {
22             if(this.ticketNumber>0)
23             {
24                 System.out.println(Thread.currentThread().getName()+"卖出"+ticketNumber--+"号票");
25             }            
26         }    
27     }
28 }
复制代码

结果:

1号窗口卖出10号票
3号窗口卖出8号票
2号窗口卖出9号票
3号窗口卖出6号票
1号窗口卖出7号票
3号窗口卖出4号票
2号窗口卖出5号票
3号窗口卖出2号票
1号窗口卖出3号票
2号窗口卖出1号票

 

这两种方法的结果很明显易见......................

比较两种方式的区别:

  使用继承的话,资源不能共享。

  继承方式,继承了Thread之后就不能继承其它类

  从代码的简单性来说,继承方式简单些。

推荐使用接口方法,方便以后拓展,而且资源共享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值