1、Java多线程应用

Java多线程应用
  1. 什么是进程?
    进程是操作系统的结构,是一次程序的执行,是程序在一个数据集合运行的过程,是系统的进行资源分配和调度的独立单位?
  2. 什么是线程?
    线程是进程中具体的搬运工,由进行分配资源进行调度,单个线程必须一个执行完成后,才能执行另外一个,但是多线程操作系统windows,就可以在一个任务执行处于等待的时候,cpu空闲的时间去执行另外一个任务,各个任务之前的快速切换,可以造成,多任务同时执行的效果。
  3. 实现线程的方法
    3.1 继承Thread类

package threadMainTest;
public class ManyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
}
}

 主方法调用

package threadMainTest;

public class ThreadMainTest {
	public static void main(String[] args) throws InterruptedException {
	ManyThread mT = new ManyThread();
	}
}

3.2 实现Runnable接口
4. package threadMainTest;
5.
6. public class MyRunnable implements Runnable{
7.
8. @Override
9. public void run() {
10. System.out.println(“使用实现runnable方式来实现线程”);
11. }
12.
13. }
 主方法调用
package threadMainTest;
public class ThreadMainTest {
public static void main(String[] args) throws InterruptedException {
MyRunnable mr = new MyRunnable();
Thread tr = new Thread(mr);
tr.start();
}
}
 因为Thread类是继承的Runnable接口,所以这儿Thread构造函数,不仅可以传入一个Runnable对象,还可以传入一个Thread对象。
4. 线程常用的方法
4.1 currentThread()方法,返回当前代码块正在被哪个线程调用
5 package threadMainTest;
6 public class MyThread extends Thread{
7 public MyThread() {
8 System.out.println(“CountOperate begin”);
9 System.out.println(“Thread.currentThread().getName()=”+Thread.currentThread().getName());
10 System.out.println(“this.getName()”+this.getName());
11 System.out.println(“CountOperate end”);
12 }
13 @Override
14 public void run() {
15 System.out.println(“run begin”);
16 System.out.println(“Thread.currentThread().getName()=”+Thread.currentThread().getName());
17 System.out.println(“this.getName()=”+this.getName());
18 System.out.println(“run end”);
19 }
20 }
 主方法调用
21 MyThread my = new MyThread();
22 Thread t = new Thread(my);
23 t.setName(“A”);
24 t.start();
 结果展示
25 CountOperate begin
26 Thread.currentThread().getName()=main
27 this.getName()Thread-0
28 CountOperate end
29 run begin
30 Thread.currentThread().getName()=A
31 this.getName()=Thread-0
32 run end
 如果将主方法代码修改为下面
MyThread my = new MyThread();
Thread t = new Thread(my);
t.setName(“A”);
t.start();
my.setName(“A”);
my.start();
 结果展示
CountOperate begin
Thread.currentThread().getName()=main
this.getName()Thread-0
CountOperate end
run begin
Thread.currentThread().getName()=A
this.getName()=A
run end
run begin
Thread.currentThread().getName()=A
this.getName()=A
4.2 isActive()方法,用于显示线程的活跃状态,活跃状态就是线程已经启动并且尚未终止。线程处于正在运行或者存在运行的状态,就认为线程是存活的,如果存活返回true,否则返回false.
4.3 Sleep()是在指定的毫秒数内,让正在执行的线程休眠,this.currentThrad()就是指正在执行的线程
4.4 Getid()取得线程唯一的标识符,即表示线程的ID值
5. 停止线程
5.1 stop(),suspend(),resume(),都可以用于终止线程,但是他们都是强制终止线程,不安全,所以已经被移除(deprecated),在未来的JAVA版本中也将不可以使用,目前使用Interrupt(),终止线程,但是不会终止正在运行的线程,需要加入一个判断才能完成线程的终止。
package threadMainTest;

public class isThreadActive extends Thread{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println(“i=”+ i++);
}
}
}
 主函数调用
package threadMainTest;

public class isThreadActive extends Thread{
@Override
public void run() {
for (int i = 0; i < 500; i++) {
System.out.println(“i=”+ i++);
}
}
}
 结果展示
i=378
i=380
i=382
i=384
i=386
i=388
i=390
i=392
i=394
i=396
i=398
i=400
i=402
i=404
线程并没有被关闭,是因为interrupt()不能关闭正在运行的线程
5.2 interrupted() 测试当前线程是否已经被中断(当判断完毕后,如果线程被中断,会清楚当前被中断的状态),inInterrupted()测试线程是否已经被中断.没有清除功能
6. package threadMainTest;
7.
8. public class Run2 {
9. public static void main(String[] args) {
10. Thread.currentThread().interrupt();
11. System.out.println(“是否停止1?”+Thread.interrupted());
12. System.out.println(“是否停止2?”+Thread.interrupted());
13. }
14. }
 结果展示
15. 是否停止1?true
16. 是否停止2?false
 如果是inInterrupted()
17. package threadMainTest;
18.
19. public class Run2 {
20. public static void main(String[] args) {
21. try {
22. isThreadActive thread = new isThreadActive();
23. thread.start();
24. Thread.sleep(5);
25. thread.interrupt();
26. System.out.println(“是否停止1?”+thread.isInterrupted());
27. System.out.println(“是否停止2?”+thread.isInterrupted());
28. } catch (InterruptedException e) {
29.
30. e.printStackTrace();
31. }
32. }
33. }
 结果展示
34. i=637
35. 是否停止1?true
36. 是否停止2?true
37. i=638
38. i=639
5.3 调用interrupt方法后,后for后面的语句还是在运行(如何使线程停止,程序不运行)
6 package thread;
7
8 public class ThreadTest extends Thread{
9 @Override
10 public void run() {
11 int time = 0;
12 for (int i = 0; i < 500000; i++) {
13 if(this.interrupted()) {
14 System.out.println("已经是停止状态了,我要退出了 ");
15 break;
16 }
17 System.out.println("i = " + (i+1));
18 }
19 System.out.println(“还是在运行”);
20 }
21 }
 展示结果
22 i = 394330
23 i = 394331
24 i = 394332
25 已经是停止状态了,我要退出了
26 还是在运行
27 end!

 如何使停止线程后程序就不在运行,使用异常退出
28 package thread;
29 public class ThreadTest extends Thread{
30 @Override
31 public void run() {
32 super.run();
33 try {
34 for (int i = 0; i < 500000; i++) {
35 if(this.interrupted()) {
36 System.out.println("已经是停止状态了,我要退出了 ");
37 throw new InterruptedException();
38 }
39 System.out.println("i = " + (i+1));
40 }
41 System.out.println(“还是在运行”);
42 } catch (InterruptedException e) {
43 System.out.println(“进入了线程的异常捕获方法”);
44 e.printStackTrace();;
45 }
46 }
47 }
 主方法
48 package thread;
49
50 public class ThreadMainTest {
51 public static void main(String[] args) {
52 try {
53 ThreadTest thread = new ThreadTest();
54 thread.start();
55 Thread.sleep(100);
56 thread.interrupt();
57 } catch (InterruptedException e) {
58 System.out.println(“main catch”);
59 e.printStackTrace();
60 }
61 System.out.println(“end!”);
62 }
63 }

 结果展示
64 i = 341617
65 已经是停止状态了,我要退出了
66 进入了线程的异常捕获方法
67 end!
68 java.lang.InterruptedException
69 at thread.ThreadTest.run(ThreadTest.java:11)
 如何停止沉睡中的线程
package thread;

public class ThreadTest extends Thread{
@Override
public void run() {
super.run();
try {
System.out.println(“run begin”);
Thread.sleep(200000);
System.out.println(“run end”);
} catch (InterruptedException e) {
System.out.println(“线程停止,目前状态为:” + this.isInterrupted());
e.printStackTrace();
}
}
}
 展示结果:
run begin
线程停止,目前状态为:false
end!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at thread.ThreadTest.run(ThreadTest.java:9)
 如果先执行interrupt停止再sleep会怎么样
package thread;

public class ThreadTest extends Thread{
@Override
public void run() {
super.run();
try {
for (int i = 0; i < 500; i++) {
System.out.println("i= " + (i+1));
}
System.out.println(“run begin”);
Thread.sleep(200000);
System.out.println(“run end”);
} catch (InterruptedException e) {
System.out.println(“先停止,再遇到Sleep,然后进入catch”);
e.printStackTrace();
}
}
}
主方法
package thread;

public class ThreadMainTest {
public static void main(String[] args) {
ThreadTest thread = new ThreadTest();
thread.start();
thread.interrupt();
System.out.println(“end!”);
}
}
 使用return停止线程
package thread;

public class ThreadTest extends Thread{
@Override
public void run() {
super.run();
while(true) {
if(this.isInterrupted()) {
System.out.println(“停止了”);
return;
}
System.out.println("time= " + System.currentTimeMillis());
}

}

}
主方法:
package thread;

public class ThreadMainTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest thread = new ThreadTest();
thread.start();
Thread.sleep(2000);
thread.interrupt();
}
}
结果展示:
time= 1542850294016
time= 1542850294016
time= 1542850294016
time= 1542850294016
time= 1542850294016
time= 1542850294016
time= 1542850294016
停止了
 不过还是建议用抛异常的方式来停止线程,因为Catch块中还可以将异常向上抛,使线程停止的事件得以传播!
6. 暂停线程
6.1 suspend()暂停现场,resume()恢复线程使用
7. package threadMainTest;
8.
9. public class ThreadMainTest {
10. @SuppressWarnings(“deprecation”)
11. public static void main(String[] args) throws InterruptedException {
12. MyThread my = new MyThread();
13. my.start();
14. Thread.sleep(5000);
15. my.suspend();//已经被移除,可以用但是还是有缺陷,在被调用过程中不会释放所占用的锁,容易造成死锁
16. System.out.println("A= " + System.currentTimeMillis()+ "A= " + my.getI());
17. System.out.println("B= " + System.currentTimeMillis()+ "B= " + my.getI());
18. my.resume();
19. Thread.sleep(5000);
20. my.suspend();
21. System.out.println("C= " + System.currentTimeMillis()+ "C= " + my.getI());
22. System.out.println("D= " + System.currentTimeMillis()+ "D= " + my.getI());
23. }
24. }
 结果展示
25. A= 1542871355220A= -1084856100
26. B= 1542871355220B= -1084856100
27. C= 1542871405220C= 929579568
28. D= 1542871405220D= 929579568
6.2 Yield()放弃当前的CPU,资源,让给其它任务来占用CPU
package thread;

public class ThreadTest extends Thread{
@Override
public void run() {
long time = System.currentTimeMillis();
int count = 0 ;
while(count < 500000) {
//Thread.yield();
count ++;
}
long endTime = System.currentTimeMillis();
System.out.println(“用时” + (endTime-time) + “毫秒”);
}
}
 结果显示:

 使用Thread.yield()后,把CPU让给其他资源,导致速度变慢

6.3 优先级
6.3.1 继承性
线程的优先级具有继承性,A调用B线程,所以B线程的优先级跟A线程一样
package threadMainTest;

public class MyThread extends Thread{
@Override
public void run() {
System.out.println("MyThread run is priority = " + this.getPriority());
}
}
 主方法调用
package threadMainTest;

public class ThreadMainTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("main thread begin priority = " + Thread.currentThread().getPriority());
Thread.currentThread().setPriority(6);
System.out.println("main thread begin priority = " + Thread.currentThread().getPriority());
new MyThread().start();
}
}
 结果
main thread begin priority = 5
main thread begin priority = 6
MyThread run is priority = 6
6.3.2使用setPriority()方法设置优先级
高优先级的线程大部分总是先执完,但是并不代表所有高优先级的线程会限制性,线程的优先级与代码的调用顺序无关,线程执行具有随机性,不一定每次高的线程都先执行
6.3.3守护线程
守护线程,是伴随着需要守护的线程的,当最后一个需要守护的线程停止时,守护线程才会随着JVM结束,最典型的的就是GC垃圾回收机制

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值