JavaSE笔记7.2-多线程-创建线程

一. 方法1:继承Java.lang.Thread类

通过对API的查找,Java已经提供了对线程这类事物的描述,就是Java.lang.Thread类.。

1. 步骤

(1)继承Thread类
(2)复写Thread类中的run方法
将自定义的代码存储在run方法,让线程运行
(3)调用线程的start方法
该方法有2个作用:启动线程&调用run方法

class Demo extends Thread//自定义线程,继承Thread类
{
	public void run()//复写run方法
	{
		System.out.println("Demo run");
	}
}


class ThreadDemo 
{
	public static void main(String[] args) 
	{
		Demo d=new Demo();//创建好一个线程
		d.start();
	}
}

输出结果为:
Demo run

2. 随机性

多线程的一个特性:随机性
因为多个线程都在获取CPU的执行权。谁抢到谁执行;至于执行多长,CPU决定

class Demo extends Thread//自定义线程,继承Thread类
{
	public void run()//复写run方法
	{
		for(int x=0;x<60;x++)
			System.out.println("Demo run---"+x);
	}
}


class ThreadDemo 
{
	public static void main(String[] args) 
	{
		Demo d=new Demo();//创建好一个线程
		d.start();//开启线程,并执行该线程的run方法
		for(int x=0;x<60;x++)
			System.out.println("Hello World---"+x);
	}
}

运行结果是:
在这里插入图片描述

3. 为什么要覆盖run方法

Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法。
(主线程的代码存储在main函数中)

4. 多线程练习

创建2个线程,和主线程交替运行

class Test extends Thread
{
	private String name;
	Test(String name)
	{
		this.name=name;
	}
	public void run()
	{
		for(int x=0;x<60;x++)
			System.out.println(name+" run---"+x);
	}
}
class ThreadTest 
{
	public static void main(String[] args) 
	{
		Test t1=new Test("one");
		Test t2=new Test("two");
		t1.start();
		t2.start();
		for(int x=0;x<60;x++)
			System.out.println("main---"+x);
	}
}

运行结果是:
在这里插入图片描述

5. 获取线程对象以及名称
  • 线程都有自己默认的名称:Thread-编号,该编号从0开始
  • 设置线程名称:复写父类setName(String name)或构造函数Thread(String name)
  • 获取线程名称:getName()
  • 获取当前线程对象:static Thread currentThread()
(1)获取线程默认名称
class Test extends Thread
{
	private String name;
	Test(String name)
	{
		/*
         隐式 super();
         即 Thread();
         线程都有自己默认的名称:Thread-编号,该编号从0开始
         */
		this.name=name;
	}
	public void run()
	{
		/*
		获取线程名称:getName()
		*/
		for(int x=0;x<60;x++)
			System.out.println(this.getName()+" run---"+x);
	}
}
class ThreadTest 
{
	public static void main(String[] args) 
	{
		Test t1=new Test("one");
		Test t2=new Test("two");
		t1.start();
		t2.start();
		for(int x=0;x<60;x++)
			System.out.println("main---"+x);
	}
}

运行结果是:
在这里插入图片描述

(2)设置线程名称
class Test extends Thread
{
    Test(String name)
    {
        /*
        即Thread(name);
        修改线程名称为name
        */
        super(name);
    }
    public void run()
    {
    	/*
		获取线程名称:getName()
		*/
        for(int x=0;x<60;x++)
            System.out.println(this.getName()+" run---"+x);
    }
}
class ThreadTest
{
    public static void main(String[] args)
    {
        Test t1=new Test("one");
        Test t2=new Test("two");
        t1.start();
        t2.start();
        for(int x=0;x<60;x++)
            System.out.println("main---"+x);
    }
}

在这里插入图片描述

(3)获取当前线程对象
class Test extends Thread
{
	Test(String name)
	{
		/*
        即Thread(name);
        修改线程名称为name
        */
		super(name);
	}
	public void run()
	{
		/*
		Thread.currentThread()获取当前线程对象
		*/
		for(int x=0;x<60;x++)
			System.out.println(Thread.currentThread().getName()+" run---"+x);
	}
}
class ThreadTest 
{
	public static void main(String[] args) 
	{
		Test t1=new Test("one");
		Test t2=new Test("two");
		t1.start();
		t2.start();
		for(int x=0;x<60;x++)
			System.out.println("main---"+x);
	}
}

在这里插入图片描述

二. 方法2:实现Runnable接口

1. 引入

需求:简单的卖票程序
多个窗口卖票

(1)使用继承Thread类的方法实现
class Ticket extends Thread
{
	private int num=100;
	public void run()
	{
		while(true)
		{
			if(num>0)
			{
				System.out.println(currentThread().getName()+"sale: "+num--);
			}
		}
	}
}

class TicketDemo 
{
	public static void main(String[] args) 
	{
		Ticket t1=new Ticket();
		Ticket t2=new Ticket();
		Ticket t3=new Ticket();
		Ticket t4=new Ticket();

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

问题:每一个对象都有100张票
需要让4个对象共享相同的100张票

(2)使用static共享变量
class Ticket extends Thread
{
	private static int num=100;//4个对象共享100张票
	public void run()
	{
		while(true)
		{
			if(num>0)
			{
				System.out.println(currentThread().getName()+"sale: "+num--);
			}
		}
	}
}

class TicketDemo 
{
	public static void main(String[] args) 
	{
		Ticket t1=new Ticket();
		Ticket t2=new Ticket();
		Ticket t3=new Ticket();
		Ticket t4=new Ticket();

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

问题:static的生命周期太长,不建议使用这种方法

(3)使用实现Runnable接口的方法实现
2. 步骤

(1)定义类实现Runnable接口
(2)覆盖Runnable接口中的run方法
将线程要运行的代码存放在该run方法中
(3)通过Thread类建立线程对象
(4)将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数

为什么要将Runnable接口的子类对象传递给Thread的构造函数?

因为自定义的run方法所属的对象是Runnable接口的子类对象,
所以要让线程去指定指定对象的run方法,
就必须明确该run方法所属对象
(5)调用Thread类的start方法开启线程并调用Runnable接口子类中的run方法

//(1)定义类实现Runnable接口
class Ticket implements Runnable
{
	private int num=100;
	//(2)覆盖Runnable接口中的run方法
	public void run()
	{
		while(true)
		{
			if(num>0)
			{
				System.out.println(Thread.currentThread().getName()+"...sale:"+num--);
			}
		}
	}
}
class TicketDemo
{
	public static void main(String[] args) 
	{
		Ticket t=new Ticket();//这不是一个线程

		//(3)通过Thread类建立线程对象
		//(4)将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		Thread t3=new Thread(t);
		Thread t4=new Thread(t);

		//(5)调用Thread类的start方法开启线程并调用Runnable接口子类中的run方法

		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

三. 继承方法与实现方法的区别

1. run方法

继承Thread:线程代码存放在Thread子类的run方法中
实现Runnable:线程代码存放在接口的子类的run方法中

2. 优缺点

继承Thread:线程不能继承其他的类;但是可以使用this指针来获取线程的名字等信息。
实现Runnable:线程类还可以继承其他的类;可以用来创建多个线程,可以实现资源共享。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值