线程的构造与运行

		Thread t=Thread.currentThread();//引用当前正在运行的线程,意义何在?

两大主要方式的框架
① 直接继承 Thread 类
② 实现 Runnable 接口,把对象放在 Thread 对象中。

  • 构造线程方式一:直接继承Thread类
    线程必须先new,再start(),注意:
    (1)start()源自Thread类,start()不能被重写、一个线程不能多次start()、
    (2)线程start(),不等同于线程立即能够执行,仅仅表示线程“具备执行的条件”,
    至于何时执行,有JVM决定;
    (3)main是守护线程,只有当main中直接或间接产生的所有线程都结束,main才会结束
    换言之,由于main是程序的入口,故main实际上是最后结束的线程。

需求:线程中有变量int型data,让data+2重复50次
效果:若data是1,则输出1、3、5、7、……51;
若data是2,则输出2、4、6、8、……52;

class Thread_A extends Thread{
	private int data;
	private String name;
	public Thread_A(int x, String s) { data=x; name=s;}
	public void run() {//注:这里就是线程对应的代码段
		//注:作为线程的run,必须用publi void ,且无参
		//    因为这个run,实际上就是重写 Runnable接口中的run
		//注意:Thread类也重写了Runnable接口
		System.out.print(name+"开始:\n");
		for(int i=0; i<50; i++) {data=data+2;
			System.out.print(data+" ");
		}
		System.out.print(name+"结束.\n");
	}
}
class App1{
	public static void main(String[] args) {
		System.out.print("main开始 ");
		Thread_A a=new Thread_A(1,"奇数线程"); //创建线程,但未启动
		Thread_A b=new Thread_A(2,"偶数数线程");
		a.start(); b.start();//启动线程,开启线程声明周期,即线程开始执行
		System.out.print("main结束 ");
	}
}
  • 构造线程的方式二:
    (1)让类Thread_B实现Runnable接口(当然必须实现接口中的run方法)
    (2)构造Thread_B的对象,并将该对象填入Thread的构造器中
    如,希望“开车郊游”,类比:
    方式一:自己有车、自己开
    方式二:自己会驾驶(即有run()), 但开别人的车(即另造一个Thread)
    这种方式的好处:不影响类的继承(注:java是单继承)

Thread_B的对象不是线程,仅仅具备线程体(即Runnable中的run())
实现线程必须要有Thread类

class Thread_B implements Runnable{
	private int data; private String name;
	Thread_B(int x, String s){ data=x; name=s; }
	public void run(){
		System.out.print(name+"开始 ");
		if(data<=0)return;
		int i=1;
		while(i*data<50) {
			System.out.print(i*data+" "); i++;
		}
		System.out.print(name+"结束.\n ");
	}	
}
public class BuildThread2 {
	public static void main(String[] args) {
		System.out.print("main开始  ");
		Thread_B t2=new Thread_B(2,"二线程 ");
		Thread_B t3=new Thread_B(3,"三线程 ");
		Thread_B t5=new Thread_B(5,"五线程 ");
		//注意:t2、t3、t5不是线程对象
		Thread t22=new Thread(t2);//t22才是线程对象
		Thread t33=new Thread(t3);//t33才是线程对象
		Thread t55=new Thread(t5);//t55才是线程对象
		//注意:上述仅仅构造出线程对象,尚未启动
		t22.start();t33.start();t55.start();
		System.out.print("main结束.\n ");	}
}

直接造Thread_C的对象,并 start() ,即伪造start()

class Thread_C implements Runnable{
	private int data; 
	private Thread t; //不可少,用于
	Thread_C(int x, String s){ 
		data=x; 
		t=new Thread(this); //此句作用: 先造Runnable的实现对象,再将该对象填入Thread对象中
		t.setName(s); 
	}
	public void start() {t.start(); }//伪造的start()
	public void run(){
		System.out.print(t.getName()+"开始 ");
		if(data<=0)return;
		int i=1;
		while(i*data<50) {
			System.out.print(i*data+" "); i++;
		}
		System.out.print(t.getName()+"结束.\n ");
	}	
}
class App3{
	public static void main(String[] args) {
		System.out.print("main开始  ");
		Thread_C t2=new Thread_C(2,"二线程 ");
		Thread_C t3=new Thread_C(3,"三线程 ");
		Thread_C t5=new Thread_C(5,"五线程 ");
		//注意:上述仅仅构造出线程对象,尚未启动
		t2.start();t3.start();t5.start();
		System.out.print("main结束.\n ");	}
}
  • 引入线程的目的:旨在实现并发程序设计。
  • 并发程序设计的目的:
  1. 现实中,有很多并发需求,无法用顺序型程序实现,如游戏中二人对打、模拟核爆炸
  2. 并发能提高资源的使用效率,如输入输出占用CPU少,可将相关CPU时间片分给其它计算任务
  • OS中,进程实现了任务间的并发,线程实现了任务内的并发(即程序员决定如何并发)
    如:在线播放音视频,需要先下载到缓存,再播放。
    类似这种并发,只能由程序员决定何时进行那个操作,
    不能播放、下载不能以任意次序进行,即OS不知晓二者是何种关

  • 单个线程的执行是顺序的,多个线程执行结果不确定的原因是:
    多个线程(即若干条语句)在不确定的时间、不确定的位置进行了交错
    如:线程1有三条语句:a、b、c;线程2有2条语句:x、y
    可能的执行结果有axybc、axbcy、xabcy、……

  • 线程由三要素组成:
    ① 虚拟CPU(即Thread类)
    ② 线程体(Runnable接口中的run)
    ③ 共享资源

注意:三者必须同时具备。类比:线程就是【行驶中】的汽车 虚拟CPU–汽车;线程体—司机或智能驾驶机器人;共享资源 — 道路;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值