标签:interrupt 静态方法 stat ace 获得 情况下 class 前端 catch
创建一个线程,Java提供三种方法
(1)通过实现Runnable接口,重写run方法
(2)通过继承Thread类本身,--必须重写
(3)通过Callable和Future创建线程
Thread类的方法
void start()使该线程开始执行,Java虚拟机调用该线程的run方法。
final void setName(String name)改变线程名称,使之与参数name相同
setPriority(int priority)更改线程的优先级
join(long millisec)等待该线程终止的时间最长为milli毫秒
interrupt()中断线程
boolean isAlive()测试线程是否处于活动状态
上述方法被Thread对象调用
下面的方法是Thread类的静态方法static
yield()放弃CPU的使用权力
sleep(long millisec)休眠线程
currentThread()获得正在执行的线程对象
概念解析:
并行:是真正的同时。
并发:通过CPU调度算法,用户看上去同时执行,实际上从CPU层面上不是真正同时。
线程安全:并发情况下,多线程使用,线程调度顺序不影响任何结果。
同步:Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问称为线程安全的--结果正确。
Thread和Runnable的区别
如果一个类继承Thread,则不合适资源共享,但是如果实现了Runnable接口,则很容易实现资源共享。
线程是CPU的调度单位,进程是操作系统的调度单位。
Method类中有个方法invoke()
public Object invoke(Object obj,Object ...args)
通俗点讲就是:对象调用的方法(对象.参数)
守护线程(DaemonThread)
守护线程具有最低的优先级;
是用来服务用户线程的。
(1)thread.setDaemon(true)必须在thread.start()之前设置。
(2)在Daemon线程中产生的新的线程也是Daemon的。
(3)守护线程不去访问固有的资源,如文件,数据库。
用户线程(userThread)
Thread和Runnable创建出来的线程。
线程的生命周期大体分为5种状态
1.New:通过new创建了Thread类或其子类对象。
2.Runnable: a)指Thread类对象调用了start()方法,这时的线程就等待时间片轮转到自己这,以便获得CPU;b)线程在处于Runnable状态时并没有运行完自己的run方法,时间片用完之后回到Runnable状态; c) 处于Blocked状态的线程结束当前的Blocked状态之后重新回到Runnable状态。
3.Running:线程已获CPU运行。
4.Dead:处于Running的线程,执行完run方法之后,就变成了Dead状态。
5.Blocked:处于Running状态的线程出于某种原因,让出当前CPU 给其他线程。
线程的创建与启动
继承Thread类:重写run方法
1 package NiuMuThread; 2 3 public class MyThread extends Thread{ 4 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 for(int i=0;i<100;i++) { 9 // 线程的静态方法-----当前线程----的名字 10 System.out.println(Thread.currentThread().getName()+":"+i); 11 try { 12 Thread.sleep(100); 13 } catch (InterruptedException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } 17 } 18 } 19 }
实现Runnable接口:重写run方法
1 package NiuMuThread; 2 3 public class MyThread2 implements Runnable{ 4 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 for(int i=0;i<100;i++) { 9 // 线程的静态方法-----当前线程----的名字 10 System.out.println(Thread.currentThread().getName()+":"+i); 11 try { 12 Thread.sleep(100); 13 } catch (InterruptedException e) { 14 // TODO Auto-generated catch block 15 e.printStackTrace(); 16 } 17 } 18 } 19 }
测试:
1 package NiuMuThread; 2 3 public class Test { 4 5 public static void main(String[] args) { 6 //第一个线程 7 MyThread thread=new MyThread(); 8 //第三个线程 9 MyThread2 r=new MyThread2(); 10 11 Thread th2=new Thread(r); 12 thread.start();//启动线程 13 th2.start(); 14 15 //第二个线程 16 for(int i=0;i<100;i++) { 17 // 线程的静态方法-----当前线程----的名字 18 System.out.println(Thread.currentThread().getName()+":"+i); 19 try { 20 Thread.sleep(100); 21 } catch (InterruptedException e) { 22 // TODO Auto-generated catch block 23 e.printStackTrace(); 24 } 25 } 26 } 27 }
注意:通过实现Runnable接口的,需要 new Thread(runnable),才能创建线程对象
***在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
一些常见的问题
1.线程的名字,一个运行中的线程总是有名字的,名字有两个来源,一是虚拟机自己给的名字,或者是你自己定的名字。在没指定线程名字的情况下,虚拟机会为线程指定名字,主线程的名字是main,非主线程的名字不确定。
2.线程都可以设置名字,也可以获取线程的名字。
3.获取当前线程的对象的方法是:Thread.currentThread();
4.在上面代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。
5.当线程目标run()方法结束时线程完成。
6.一旦线程启动,它就永远不能在重新启动。只有一个新的线程可以被重新启动,并且只能一次。一个可运行的线程或者死线程可以被重新启动。
7.线程的调度是JVM的一部分,在一个CPU的机器上,实际上一次只能运行一个线程。一次只有一个线程栈运行。JVM线程调度程序决定实际运行哪个处于可运行状态的线程。
众多可运行线程中的某一个会被选中作为当前线程。可运行线程被选择的顺序是没有保障的。
8.尽管通常采用队列形式,但这是没有保障的。队列形式是指当一个线程完成“一轮”时,它移到可运行队列的尾部等待,直到它最终排队到该队列的前端为止,它才能被再次选中。事实上,我们把它称为可运行池而不是一个可运行队列,目的是帮助认识线程并不都是以某种有保障的顺序排列。
9.尽管我们没有无法控制线程调度程序,但可以通过别的方式来影响线程的调度方式。
标签:interrupt 静态方法 stat ace 获得 情况下 class 前端 catch
原文地址:https://www.cnblogs.com/xjs1874704478/p/10742672.html