进程与线程
进程:是一个正在执行的程序;计算机中正在运行的程序实例;可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。
线程:是"进程"中某个单一顺序的控制流。也被称为轻量进程(lightweight processes)。计算机科学术语,指运行中的程序的调度单位。
进程与线程:
简而言之,一个程序至少有一个进程,一个进程至少有一个线程.
线程的创建
(摘录子JDK1.6文档)
创建新执行线程有两种方法。一种方法是将类声明为
Thread
的子类。该子类应重写Thread
类的run
方法。接下来可以分配并启动该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
然后,下列代码会创建并启动一个线程:
PrimeThread p = new PrimeThread(143); p.start();
创建线程的另一种方法是声明实现
Runnable
接口的类。该类然后实现run
方法。然后可以分配该类的实例,在创建Thread
时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
然后,下列代码会创建并启动一个线程:
PrimeRun p = new PrimeRun(143); new Thread(p).start();
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
创建实例
1.通过继承创建线程
/* 1.通过继承Thread类创建线程 2.通过复写run方法,放入线程需要运行的代码块 3.在main()线程创建线程对象 4.启动线程对象 */ package me.thread; class ThreadDemo extends Thread{ //2.复写run public void run(){ //run方法存放的是需要执行的代码,线程会从这里自动执行 System.out.println("这是 "+Thread.currentThread().getName()+" 线程"); //currentThread()为静态方法,返回线程对象 //getName()返回线程名称 //也可以用this代替 currentThread(),this也代表线程对象 System.out.println("这是 "+this.getName()+" 线程"); } } public class FirstThread{ public static void main(String[] args){ ThreadDemo coco=new ThreadDemo(); coco.start();//启动线程,还有自动执行run()方法 System.out.println("这是 "+Thread.currentThread().getName()+" 线程"); /*输出 这是 Thread-0 线程 这是 main 线程 这是 Thread-0 线程 */// } }
/* 1.用让main线程 和Thread-0线程和Thread-1线程同时运行循环打印程序,观察情况 2.让三个线程都循环打印数字50次 3. */ package me.thread; class Demo extends Thread{ private int number=10; //2.复写run public void run(){ //循环 输出50次 while(true){ System.out.println(Thread.currentThread().getName()+" "+number--); if(number == 0) break; } } } public class DemoThread1{ public static void main(String[] args){ Demo coco=new Demo(); coco.start();//启动线程,还有自动执行run()方法 Demo nina=new Demo(); nina.start(); int sum=10; while(true){ System.out.println(Thread.currentThread().getName()+" "+sum--); if(sum == 0) break; } } /*输出结果: main 10 Thread-0 10 Thread-1 10 Thread-0 9 main 9 main 8 main 7 main 6 main 5 main 4 Thread-0 8 Thread-1 9 Thread-0 7 main 3 Thread-0 6 Thread-1 8 Thread-0 5 main 2 Thread-0 4 Thread-1 7 Thread-0 3 main 1 Thread-0 2 Thread-1 6 Thread-0 1 Thread-1 5 Thread-1 4 Thread-1 3 Thread-1 2 Thread-1 1 *///因为线程执行的方式是抢占式,会出现交替的也可能出现连续抢占到CPU运行资格的现象 }
2.通过实现Runnable接口创建线程
/*
1.用实现接口的方式创建线程 2.步骤: 1.用一个类实现Runnable接口,复写run方法 2.创建已经实现Runnable接口的类的对象 3.创建线程对象并且把接口对象传过去 4.还是用start()启动线程对象 3.执行循环打印 */ package me.demothread2; public class DemoThread2 implements Runnable{ //复写run() public void run(){ for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } } public static void main(String[] args){ //2.创建DemoThread2对象 DemoThread2 coco=new DemoThread2(); //3.创建线程对象,并且把coco传过去,这样就能执行复写的run方法了 Thread t1=new Thread(coco,"线程1"); Thread t2=new Thread(coco,"线程2"); //4.启动线程 t1.start(); t2.start(); //main线程也执行循环 for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+"线程 "+i); } /*输出结果: 线程2 0 线程1 0 main线程 0 线程1 1 线程2 1 线程1 2 main线程 1 线程1 3 线程2 2 线程1 4 main线程 2 线程1 5 线程1 6 线程1 7 线程1 8 线程1 9 线程2 3 main线程 3 线程2 4 main线程 4 线程2 5 main线程 5 线程2 6 main线程 6 线程2 7 main线程 7 线程2 8 main线程 8 线程2 9 main线程 9 *///每一次运行输出顺序都有不同,还是因为线程的抢占式风格,每个线程都独立运行run部分 } }
3.继承和实现接口方式的区别
/* 1.分别用继承Thread方式和实现Runnable方式,看看能不能共享类的实例变量? 2.这个例子用继承方式 */ package me.demothread3; class Ticket_cn extends Thread{ private int ticket=10; public void run(){ while (true){ if(ticket<=0) break; System.out.println(Thread.currentThread().getName()+" 正在买票,剩余票为: "+ticket--); } } } public class DemoThread3{ public static void main(String[] args){ // 创建线程子类对象 Ticket_cn nanning=new Ticket_cn(); Ticket_cn baise=new Ticket_cn(); //启动线程 nanning.start(); baise.start(); /* Thread-1 正在买票,剩余票为: 10 Thread-0 正在买票,剩余票为: 10 Thread-1 正在买票,剩余票为: 9 Thread-0 正在买票,剩余票为: 9 Thread-1 正在买票,剩余票为: 8 Thread-0 正在买票,剩余票为: 8 Thread-1 正在买票,剩余票为: 7 Thread-1 正在买票,剩余票为: 6 Thread-0 正在买票,剩余票为: 7 Thread-1 正在买票,剩余票为: 5 Thread-0 正在买票,剩余票为: 6 Thread-1 正在买票,剩余票为: 4 Thread-0 正在买票,剩余票为: 5 Thread-1 正在买票,剩余票为: 3 Thread-0 正在买票,剩余票为: 4 Thread-1 正在买票,剩余票为: 2 Thread-0 正在买票,剩余票为: 3 Thread-1 正在买票,剩余票为: 1 Thread-0 正在买票,剩余票为: 2 Thread-0 正在买票,剩余票为: 1 *///由继承实现的多线程,成员变量是单独的,没有共享数据的现象 } }
/* 1.分别用继承Thread方式和实现Runnable方式,看看能不能共享类的实例变量? 2.这个例子用实现接口的方式 3.运用sleep()函数,证明存在安全问题 */ package me.demothread4; //1.实现线程Runnable接口,复写run() class Ticket_cn implements Runnable{ private int ticket=10; public void run(){ while (true){ if(ticket<=0) break; System.out.println(Thread.currentThread().getName()+" 正在买票,剩余票为: "+ticket--); } } } public class DemoThread4{ public static void main(String[] args){ //2.创建Ticket_cn对吸纳个 Ticket_cn com_12306= new Ticket_cn(); //3.创建线程Thread对象, Thread windows_1=new Thread(com_12306,"windows_1"); Thread windows_2=new Thread(com_12306,"windows_2"); Thread windows_3=new Thread(com_12306,"windows_3"); //Thread多个构造函数,这个可以制定线程名称 //开启线程 windows_1.start(); windows_2.start(); windows_3.start(); /*输出结果: windows_1 正在买票,剩余票为: 10 windows_3 正在买票,剩余票为: 9 windows_2 正在买票,剩余票为: 8 windows_3 正在买票,剩余票为: 6 windows_1 正在买票,剩余票为: 7 windows_3 正在买票,剩余票为: 4 windows_2 正在买票,剩余票为: 5 windows_3 正在买票,剩余票为: 2 windows_1 正在买票,剩余票为: 3 windows_2 正在买票,剩余票为: 1 */// } }
作者:YangGan
出处:http://blog.csdn.net/incyanggan
本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名Yanggan(包含链接).