多线程
2018-07-17 03:58:19来源:博客园 阅读 ()
多线程
实现多线程共有两种方法:①继承一个Thread类;②实现Runnable、Callable接口(推荐)
一、继承Thread类实现多线程
Thread是一个线程操作的核心类,定义一个线程的主类最简单的方法就是继承Thread类,而后覆写类中的run()方法。实现如下(首先定义一个主体类,而后启动多线程即为调用Thread中的start()方法):
1 class MyThread extends java.lang.Thread{//线程主体类 2 private String title; 3 public MyThread(String title){ 4 this.title = title; 5 } 6 @Override 7 public void run() {//所有的线程从此处执行 8 for (int x = 0; x<10; x++){ 9 System.out.println(this.title + ",x = " + x); 10 } 11 } 12 } 13 public class Thread { 14 public static void main(String[] args) { 15 //创建线程 16 MyThread mt1 =new MyThread("A"); 17 MyThread mt2 =new MyThread("B"); 18 MyThread mt3 =new MyThread("C"); 19 //启动多线程 20 mt1.start(); 21 mt2.start(); 22 mt3.start(); 23 } 24 }
执行结果:多个线程交替执行
二、Runnable接口实现多线程
Thread类继承的缺点是单继承局限,而Runnable则没有这个缺点,其定义如下(使用的仍是Thread类的start()方法):
class MyRunnable implements Runnable { private String title;// 共10张票 public MyRunnable(String title) { this.title = title; } @Override public void run() {//所有的线程从此处执行 for (int x= 0; x<10; x++) { System.out.println(this.title + ",x = " + x); } } } public class TestRunnable { public static void main(String[] args) { //创建线程 MyThread mt1 =new MyThread("A"); MyThread mt2 =new MyThread("B"); MyThread mt3 =new MyThread("C"); //启动多线程 new java.lang.Thread(mt1).start(); new java.lang.Thread(mt2).start(); new java.lang.Thread(mt3).start(); } }
或者使用匿名内部类来定义:
1 class MyRunnable implements Runnable { 2 private String title;// 共10张票 3 4 public MyRunnable(String title) { 5 this.title = title; 6 } 7 @Override 8 public void run() {//所有的线程从此处执行 9 for (int x= 0; x<10; x++) { 10 System.out.println(this.title + ",x = " + x); 11 } 12 13 } 14 } 15 public class TestRunnable { 16 public static void main(String[] args) { 17 new java.lang.Thread(new Runnable() { 18 @Override 19 public void run() { 20 System.out.println("Hello"); 21 } 22 }).start(); 23 } 24 }
Runnable接口可以比Thread有更好的实现数据共享的概念,即产生若干线程进行同一数据的处理操作。实现如下:
1 class MyRunnable implements Runnable { 2 private int ticket = 10;// 共10张票 3 @Override 4 public void run() {//所有的线程从此处执行 5 for (int x= 0; x<20; x++) { 6 if (this.ticket > 0) 7 System.out.println("卖票,ticket:" + ",x = " + this.ticket--); 8 } 9 10 } 11 } 12 public class TestRunnable { 13 public static void main(String[] args) { 14 MyRunnable mt = new MyRunnable(); 15 new java.lang.Thread(mt).start(); 16 new java.lang.Thread(mt).start(); 17 new java.lang.Thread(mt).start(); 18 } 19 }
执行结果:(三个线程之间的数据实现了共享)
卖票,ticket:,x = 10 卖票,ticket:,x = 8 卖票,ticket:,x = 9 卖票,ticket:,x = 6 卖票,ticket:,x = 7 卖票,ticket:,x = 4 卖票,ticket:,x = 5 卖票,ticket:,x = 1 卖票,ticket:,x = 2 卖票,ticket:,x = 3
三、Collable实现多线程
由于Runnable方法中的多线程没有返回值,难以满足某些需要一些返回值的程序,因此使用Collable来实现多线程。实现过程如下:(①定义Collable线程主体类②使用Thread中start方法启动多线程)
1 import java.util.concurrent.Callable; 2 import java.util.concurrent.FutureTask; 3 4 class MyCallable implements Callable<String>{//线程主体类 5 public String call() throws Exception{ 6 for (int x = 20; x > 0; x--) 7 System.out.println("卖票:" + x); 8 return "票卖完了……"; 9 } 10 } 11 public class TestCallable { 12 public static void main(String[] args) throws Exception{ 13 FutureTask<String> task = new FutureTask<String>(new MyCallable()); 14 new java.lang.Thread(task).start();//启动多线程 15 System.out.println(task.get()); 16 17 } 18 }
四、多线程的命名和取得
Thread类提供的线程名称的操作方法:
NO. |
方法 |
类型 |
描述 |
1 |
Public Thread(Runnable target,String name) |
构造 |
创建线程时设置好名字 |
2 |
Public final void setName(String name) |
普通 |
设置线程名字 |
3 |
Public final String getName() |
普通 |
取得线程名字 |
取得当前正在执行的线程的对象:public static Thread currentThread()
取得线程姓名执行如下:
1 class MyRunnable implements Runnable { 2 private int ticket = 10;// 共10张票 3 @Override 4 public void run() {//所有的线程从此处执行 5 for (int x= 0; x<10; x++) 6 System.out.println(java.lang.Thread.currentThread().getName() + ",x = " + x);//取得线程名字 7 } 8 } 9 public class TestRunnable { 10 public static void main(String[] args) { 11 MyRunnable mt = new MyRunnable(); 12 new java.lang.Thread(mt).start(); 13 new java.lang.Thread(mt).start(); 14 new java.lang.Thread(mt,"有名字").start(); 15 } 16 }
执行结果:
Thread-0,x = 0 有名字,x = 0 有名字,x = 1 有名字,x = 2 Thread-0,x = 1 有名字,x = 3 Thread-1,x = 0 有名字,x = 4 Thread-0,x = 2 有名字,x = 5 Thread-1,x = 1 有名字,x = 6 Thread-0,x = 3 有名字,x = 7 Thread-1,x = 2 有名字,x = 8 Thread-0,x = 4 有名字,x = 9 Thread-1,x = 3 Thread-0,x = 5 Thread-1,x = 4 Thread-0,x = 6 Thread-1,x = 5 Thread-0,x = 7 Thread-1,x = 6 Thread-0,x = 8 Thread-1,x = 7 Thread-0,x = 9 Thread-1,x = 8 Thread-1,x = 9
注:设置名字不能重复,同时中间不能修改
主方法直接调用和启动线程调用run的区别:
1 class MyRunnable implements Runnable { 2 private int ticket = 10;// 共10张票 3 @Override 4 public void run() {//所有的线程从此处执行 5 System.out.println(java.lang.Thread.currentThread().getName()); 6 } 7 } 8 public class TestRunnable { 9 public static void main(String[] args) { 10 MyRunnable mt = new MyRunnable(); 11 mt.run();//直接通过对象调用 12 new java.lang.Thread(mt).start();//通过线程调用run 13 } 14 }
执行结果:
main Thread-0
可以知道:主方法本身就是一个线程,所有的线程都是通过主线程创建并启动的
五、线程休眠
线程休眠是指让线程暂停执行一段时间后再次执行,方法:public static void sleep(long millis)throws InterruptedException,休眠时间使用毫秒作为单位。休眠操作实现如下:
1 class MySleep implements Runnable{ 2 @Override 3 public void run() { 4 for (int x = 0; x < 20; x++){ 5 try { 6 java.lang.Thread.sleep(1000);//休眠一秒 7 }catch (InterruptedException e){ 8 e.printStackTrace(); 9 } 10 System.out.println(java.lang.Thread.currentThread().getName() + ",x = " + x); 11 } 12 } 13 } 14 public class TestSleep { 15 public static void main(String[] args) { 16 MySleep mt = new MySleep(); 17 new java.lang.Thread(mt).start(); 18 new java.lang.Thread(mt).start(); 19 new java.lang.Thread(mt).start(); 20 } 21 }
注:并不是三个一起执行的,而是代码依次进入run()方法,并发执行
六、线程的优先级
优先级越高越可能先执行,但不是一定先执行。
设置优先级方法:public final void setPriority(int newPriority)
取得优先级方法:public final int getPriority
设置优先级可以通过Thread类的几个常量来确定:
最高优先级:public static final int MAX_PRIORITY、10(常量的值)
中等优先级:public static final int NORM_PRIORITY、5
最低优先级:public static final int MIN_PRIORITY、1
设置优先级实现如下:
1 class MyPrority implements Runnable{ 2 @Override 3 public void run() { 4 for (int x = 0; x < 2; x++){ 5 System.out.println(java.lang.Thread.currentThread().getName() + ",x = " + x); 6 } 7 } 8 } 9 public class TestSetPrior { 10 public static void main(String[] args) throws Exception{ 11 //查看主方法的优先级 12 System.out.println(java.lang.Thread.currentThread().getPriority()); 13 MyPrority mt = new MyPrority(); 14 java.lang.Thread t1 = new java.lang.Thread(mt,"线程A"); 15 java.lang.Thread t2 = new java.lang.Thread(mt,"线程B"); 16 java.lang.Thread t3 = new java.lang.Thread(mt,"线程C"); 17 t1.setPriority(java.lang.Thread.MIN_PRIORITY); 18 t2.setPriority(java.lang.Thread.MAX_PRIORITY); 19 t3.setPriority(java.lang.Thread.NORM_PRIORITY); 20 t1.start(); 21 t2.start(); 22 t3.start(); 23 } 24 }
执行结果为:可以知道主方法的优先级为中等优先级,最先执行的为B(最高优先级),然后是C(中等优先级),最后才是C(最低优先级)
5 线程B,x = 0 线程C,x = 0 线程B,x = 1 线程C,x = 1 线程A,x = 0 线程A,x = 1
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- DES/3DES/AES 三种对称加密算法实现 2020-06-11
- SpringBoot + Vue + ElementUI 实现后台管理系统模板 -- 后 2020-06-10
- Spring Boot 实现定时任务的 4 种方式 2020-06-10
- JSP+SSH+Mysql+DBCP实现的租车系统 2020-06-09
- Java实现的三种字符串反转 2020-06-09
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash