标签:running 控制 范围 body override rgs -- bdd 资源
方式1:继承Java.lang.Thread类,并覆盖run() 方法
package com.demo.Thread; public class ThreadDemo01 extends Thread{ public static void main(String[] args) { new ThreadDemo01().start(); } @Override public void run() { int count = 50; while(count>0) { System.out.println(count--); } } }
方式2:实现Java.lang.Runnable接口,并实现run() 方法
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { Thread th = new Thread(new Runnable() { public void run() { int count = 50; while(count>0) { System.out.println(count--); } } }); th.start(); } }
新生状态 (new)
阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况
死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有三个
String |
getName() 返回该线程的名称。 |
static void |
sleep(long millis) 在指定的毫秒数内让线程休眠 |
void |
start() 使该线程开始执行 |
Void |
join() 等待该线程终止。 |
static void |
yield() 暂停当前正在执行的线程对象,并执行其他线程 |
static Thread |
currentThread() 返回对当前正在执行的线程对象 |
sleep()使当前线程进入停滞状态(阻塞当前线程),让出CUP的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会;
sleep()是Thread类的Static(静态)的方法;因此他不能改变对象的机锁,所以当在一个Synchronized块中调用Sleep()方法是,线程虽然休眠了,但是对象的机锁并木有被释放,其他线程无法访问这个对象(即使睡着也持有对象锁)。
在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。
wait()方法是Object类里的方法;当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时失去(释放)了对象的机锁(暂时失去机锁,wait(long timeout)超时时间到后还需要返还对象锁);其他线程可以访问;
wait()使用notify或者notifyAlll或者指定睡眠时间来唤醒当前等待池中的线程。
wiat()必须放在synchronized block中,否则会在program runtime时扔出”java.lang.IllegalMonitorStateException“异常。
static void yield ()
• 让当前正在执行线程暂停,不是阻塞线程,而是将线程转入就绪状态
• 如果调用了yield方法之后,没有其他等待执行的线程,这个时候当前线程就会马上恢复执行!
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { new Thread(new YieldDemo()).start(); new Thread(new Runnable() { @Override public void run() { for(int i = 1;i <= 50;i++) { System.out.println("Thread:"+i); } } }).start(); } } class YieldDemo implements Runnable{ public void run() { for(int i = 1;i <= 50;i++) { System.out.println("YieldDemo:"+i); if(i%5==0) { System.out.println("###########礼让###########"); Thread.yield(); } } } }
void join()
合并线程,等待此线程执行完毕后,在执行其他线程,其他线程进入阻塞状态
在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了
public Thread.State getState()
返回该线程的状态。 该方法用于监视系统状态,不用于同步控制。
线程状态。线程可以处于下列状态之一:
NEW
尚未启动的线程处于这种状态
RUNNABLE
可运行线程的线程状态,就绪状态和运行状态
BLOCKED
受阻塞并等待某个监视器锁的线程处于这种状态
WAITING
无限期地等待另一个线程来执行某一特定操作的线程处于这种状态,某一线程因为调用下列方法之一而处于等待状态。
TIMED_WAITING
等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态,某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态:
TERMINATED
线程结束死亡
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { Thread t = new Thread(()-> { // 每500毫秒阻塞一次 for(int i = 0;i < 5;i++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }); // 新生状态 System.out.println("状态:"+t.getState()); // 启动线程 t.start(); // 每500毫秒查看线程的状态 for(int i = 0;i < 8;i++) { try { System.out.println("状态:"+t.getState()); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } /* 控制台输出 状态:NEW 状态:RUNNABLE 状态:TIMED_WAITING 状态:TIMED_WAITING 状态:TIMED_WAITING 状态:TIMED_WAITING 状态:RUNNABLE 状态:TERMINATED 状态:TERMINATED */ } }
Thread类 提供三种优先级常量
线程优先级1-10,
优先级越大代表被cpu优先执行的概率越大
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { // 设置线程的名字 Thread old = new Thread(new MyThread(),"老人"); Thread child = new Thread(new MyThread(),"小孩"); Thread woman = new Thread(new MyThread(),"女人"); Thread man = new Thread(new MyThread(),"男人"); // 设置优先级(必须在启动线程之前设置优先级) old.setPriority(Thread.MAX_PRIORITY); child.setPriority(Thread.MAX_PRIORITY); woman.setPriority(Thread.MIN_PRIORITY); man.setPriority(Thread.MIN_PRIORITY); // 启动线程 man.start(); woman.start(); child.start(); old.start(); // old.start(); // child.start(); // woman.start(); // man.start(); } } class MyThread implements Runnable{ public void run() { // 输出当前线程的名字和优先级 System.out.println(Thread.currentThread().getName()+"------>"+Thread.currentThread().getPriority()); } }
守护线程是给其他程提供服务用的,比如gc就是守护线程。
那么如果所有的非守护线程都执行完毕后,那么守护线程和JVM就会一起结束(因为没有可以守护的线程,当然守护线程就结束)
主线程结束后,普通线程继续执行。
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { Thread t = new Thread(()-> { // 无限循环 while(true) { try { System.out.println("我是普通线程"); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); for(int i = 1;i <= 5;i++) { try { System.out.println("main线程 time="+i); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } // 控制台结果 // main线程 time=1 // 我是普通线程 // main线程 time=2 // 我是普通线程 // 我是普通线程 // main线程 time=3 // main线程 time=4 // 我是普通线程 // 我是普通线程 // main线程 time=5 // 我是普通线程 // 我是普通线程 // 我是普通线程 // 我是普通线程 // ... // ... // ... // ... 一直输出下去 } }
设置为守护线程的时候,非守护线程全部结束后,守护线程和jVM一并结束
package com.demo.Thread; public class ThreadDemo01 { public static void main(String[] args) { Thread t = new Thread(()-> { // 无限循环 while(true) { try { System.out.println("我是普通线程"); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } }); // 设置为守护线程,如果非主线程全部结束后,守护线程将会结束 t.setDaemon(true); t.start(); for(int i = 1;i <= 5;i++) { try { System.out.println("main线程 time="+i); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } // 控制台打印 // main线程 time=1 // 我是普通线程 // 我是普通线程 // main线程 time=2 // 我是普通线程 // main线程 time=3 // 我是普通线程 // main线程 time=4 // 我是普通线程 // main线程 time=5 // 我是普通线程 } }
一
synchronized关键字的作用域有二种:
二
除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
三
synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法;
A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。
B.每个对象只有一个锁(lock)与之相关联。
参考
https://www.cnblogs.com/GarfieldEr007/p/5746362.html
标签:running 控制 范围 body override rgs -- bdd 资源
原文地址:https://www.cnblogs.com/rainouyang/p/10807113.html