Java菜鸟学习笔记--多线程篇(一):多线程简介

进程与线程



进程:是一个正在执行的程序;计算机中正在运行的程序实例;可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。

线程:是"进程"中某个单一顺序的控制流。也被称为轻量进程(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(包含链接).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值