多线程学习笔记(上)

多线程

通过Thread类

Thread类

1.直接继承Object类,并实现Runnable接口,位于java.lang。

2.封装了线程对象所需要的属性和方法。

继承Thread类,创建多线程方法之一

1.从Thread类派生一个子类,并创建子类对象。

2.子类应重写run()方法,写入需要在新线程执行的语句段。

3.调用start方法启动新线程,自动进入run()方法。

例1:

``

package NewThread;

public class MyThread {
public static void main(String[] args) {
	System.out.println("MyThread startd!");
	OtherThread thread=new OtherThread();
	thread.start();
	System.out.println("MyThread ends!");
}
}

package NewThread;

public class OtherThread extends Thread{
	int i=0;
public void run() {
	System.out.println("OtherThread started!");
	while(i<5) {
		System.out.println(i);
		i++;
	}
	System.out.println("OtherThread ends!");
}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4C3c3qUw-1596029462443)(C:\Users\User\AppData\Roaming\Typora\typora-user-images\1595946534350.png)]

总结:先实现主线程,再实现新线程,main方法调用start后不等待run()运行完就独自运行了,run()方法独自在一个线程里运行,不影响原来的main方法的运行。

线程的休眠

线程休眠的原因:为了让其他线程得到执行的机会

问题1:我们希望主线程休眠,让其他得到执行的机会、

方法:加入sleep方法。

package NewThread;

public class MyThread {
public static void main(String[] args) {
	System.out.println("MyThread startd!");
	OtherThread thread=new OtherThread();
	thread.start();
	try {
		thread.sleep(2);//休眠2毫秒
	}catch(Exception e) {}
	
	System.out.println("MyThread ends!");
}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0JXSBbMY-1596029462469)(C:\Users\User\AppData\Roaming\Typora\typora-user-images\1595947662111.png)]

结果说明,main在新线程结束后才结束。

例2:创造多线程,每个线程随机休眠一段时间,然后结束

package NewThread;

public class ThreadSleep {
public static void main(String[] args) {
	TestThread thread1=new TestThread("线程1");
	TestThread thread2=new TestThread("线程2");
	TestThread thread3=new TestThread("线程3");
	System.out.println("ThreadSleep started!");
	thread1.start();//启动线程
	thread2.start();
	thread3.start();
	System.out.println("ThreadSleep ends!");
}
}

package NewThread;

public class TestThread extends Thread{
	private int num=0;
public TestThread(String name) {
		// TODO Auto-generated constructor stub
	super(name);
	num=(int)(Math.random()*5000);//5000毫秒以内随机数
	}
public void run() {
	try {	
		System.out.println(getName()+"休眠了"+num);
	Thread.sleep(num);
	
	}
	catch(Exception e) {};
	System.out.println(getName()+"结束了");
}


}

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zFoWSPCm-1596029462481)(C:\Users\User\AppData\Roaming\Typora\typora-user-images\1595948603390.png)]

线程常用的构造方法

img

通过Runnable接口创造线程

Runnable接口

1.只有run()方法

2.Thread类实现了Runnable接口

3.便于多个线程共享资源

4.可以多继承

package NewThread;

public class ThreadSleep {
public static void main(String[] args) {
	TestThread thread1=new TestThread();
	TestThread thread2=new TestThread();
	TestThread thread3=new TestThread();
	System.out.println("ThreadSleep started!");

	new Thread(thread1,"线程1").start();
	new Thread(thread2,"线程2").start();
	new Thread(thread3,"线程3").start();
	System.out.println("ThreadSleep ends!");
}
}


package NewThread;

class TestThread implements Runnable {
	private int num=0;
	//5000毫秒以内随机数
public TestThread() {
		// TODO Auto-generated constructor stub
	
	num=(int)(Math.random()*5000);
	}
public void run() {
	try {	
		System.out.println(Thread.currentThread().getName()+"休眠了"+num);
	Thread.sleep(num);
	
	}
	catch(Exception e) {};
	System.out.println(Thread.currentThread().getName()+"结束了");
}


}

两种方法的比较

Runnable接口:

可以将CPU,代码和数据分开,还可以从其他类继承

Thread类

编写简单,直接继承。

线程内部数据共享

问题:若三个售票口卖100张门票,应该编写程序呢?

在解决这个问题之前,请看以下的代码和以上有何不同?

package NewThread;

public class ThreadSleep {
public static void main(String[] args) {
	TestThread thread1=new TestThread();
//	TestThread thread2=new TestThread();
	//TestThread thread3=new TestThread();
	System.out.println("ThreadSleep started!");

	new Thread(thread1,"线程1").start();
	new Thread(thread1,"线程2").start();
	new Thread(thread1,"线程3").start();
	System.out.println("ThreadSleep ends!");
}
}


package NewThread;

class TestThread implements Runnable {
	private int num=0;
	//5000毫秒以内随机数
public TestThread() {
		// TODO Auto-generated constructor stub
	
	num=(int)(Math.random()*5000);
	}
public void run() {
	try {	
		System.out.println(Thread.currentThread().getName()+"休眠了"+num);
	Thread.sleep(num);
	
	}
	catch(Exception e) {};
	System.out.println(Thread.currentThread().getName()+"结束了");
}


}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ANQKvlW3-1596029462496)(C:\Users\User\AppData\Roaming\Typora\typora-user-images\1596028637035.png)]

通过运行结果,我们可以发现休眠时间是一样的,这是因为我们创造了一个对象,而这对象的数据被三个线程共享。

那么我们回到售票的问题,代码如下

package NewThread;

public class TicketShopTest {
public static void main(String[] args) {
	TicketShop shop=new TicketShop();
	System.out.println("开始售卖!");
	new Thread(shop,"售票口1").start();
	new Thread(shop,"售票口2").start();
	new Thread(shop,"售票口3").start();
	
}
}

package NewThread;

public class TicketShop implements Runnable{
	int i=100;
	@Override
	public void run() {
		// TODO Auto-generated method stub
	
		while(i>0) {
			System.out.println(Thread.currentThread().getName()+"正在售卖第"+i--+
			"张票");
		}
	}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-25olNijC-1596029462502)(C:\Users\User\AppData\Roaming\Typora\typora-user-images\1596029254835.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黑mmd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值