新建、初始状态(New) :线程对象被创建后就进入了新建状态,Thread thread = new Thread();
就绪(Runnable):也被称之为“可执行状态”,当线程被new出来后,其他的线程调用了该对象的start()方法,即thread.start(),此时线程位于“可运行线程池”中,只等待获取CPU的使用权,随时可以被CPU调用。进入就绪状态的线程除CPU之外,其他运行所需的资源都已经全部获得。
运行(Running):线程获取CPU权限开始执行。注意:线程只能从就绪状态进入到运行状态。
阻塞(Bloacked):阻塞状态是线程因为某种原因放弃CPU的使用权,暂时停止运行,直到线程进入就绪状态后才能有机会转到运行状态。
阻塞的情况分三种:
(1)等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池中”。进入这个状态后是不能自动唤醒的,必须依靠其他线程调用notify()或者notifyAll()方法才能被唤醒。
(2)同步阻塞:运行的线程在获取对象的(synchronized)同步锁时,若该同步锁被其他线程占用,则JVM会吧该线程放入“锁池”中。
(3)其他阻塞:通过调用线程的sleep()或者join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新回到就绪状态
死亡(Dead):线程执行完了或因异常退出了run()方法,则该线程结束生命周期。
wait notify (synchronized block中中使用,Object.wait())wait方法就是使得当前线程处于waiting等待阻塞状态,但是会释放锁,使得其他线程可以使用同步控制块或者方法
notify的话会解除等待阻塞状态,进入就绪状态,是唤醒的意思
即当前线程会从运行状态进入到休眠(阻塞)状态,sleep让出了cpu的执行权,并不会释放同步资源锁
yield (任何地方可以使用,Threa.yield())让步,它能够让当前线程从运行状态进入到就绪状态,以允许具有相同优先级的其他线程获得运行机会
join (任何地方可以使用,Threa.join())如果在一个线程A中调用另一个线程B的join方法,线程A将会等待线程B执行完毕后再执行
package com.test.joinTest;
class JoinDemo implements Runnable {
@Override // 子线程任务
public void run() {
for (int x = 1; x <= 40; x++) {
System.out.println(Thread.currentThread().getName() + "===" + x);
}
}
}
public class JoinTest {
public static void main(String[] args) {
JoinDemo jd = new JoinDemo();
Thread t1 = new Thread(jd);
Thread t2 = new Thread(jd);
t1.start();
t2.start();
try {
//等待该线程结束
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 主线程任务
for (int x = 1; x <= 50; x++) {
System.out.println(Thread.currentThread().getName() + "===" + x);
}
System.out.println("over");
}
}
synchronized
方式1:代码块
package com.test.SynchronizedTest;
public class codeBlock {
public static void main(String args[]){
Sync[] syncs = new Sync[5];
Object lock = new Object();
for (int i = 0; i < syncs.length; i++) {
syncs[i] = new Sync(lock);
}
for(Sync sync : syncs){
sync.start();
}
}
}
class Sync extends Thread{
Object syncObj;
public Sync(Object syncObj) {
this.syncObj = syncObj;
}
public void run(){
synchronized (syncObj) {
System.out.println(Thread.currentThread().getName()+"running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"over...");
}
}
}
方式二:类
package com.test.SynchronizedTest;
public class StaticClass {
public static void main(String args[]){
SyncTest2[] syncs = new SyncTest2[5];
for (int i = 0; i < syncs.length; i++) {
syncs[i] = new SyncTest2();
}
for(SyncTest2 sync : syncs){
sync.start();
}
}
}
class SyncTest2 extends Thread{
public void run(){
synchronized (StaticClass.class) {
System.out.println(Thread.currentThread().getName()+"running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"finish..");
}
}
}
方式三:方法
synchronized修饰普通方法中的同步锁就是这个对象本身,即"this"。
package com.test.SynchronizedTest;
import java.util.TreeMap;
public class FunctionTest {
public static void main(String[] args) {
Thread[] syncs = new Thread[5];
SyncTest3 syncTest3 = new SyncTest3();
for (int i = 0; i < syncs.length; i++) {
syncs[i] = new Thread(syncTest3);
}
for(Thread sync : syncs){
sync.start();
}
}
}
class SyncTest3 implements Runnable {
public synchronized void test() {
System.out.println(Thread.currentThread().getName() + "running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "over...");
}
@Override
public void run() {
test();
}
}
方式四:静态方法
synchronized作用于静态方法时,跟使用方式二中类对象作为静态锁的效果是一样的,此时的类对象就是静态方法所属的类
package com.test.SynchronizedTest;
public class StaticFunctionTest {
public static void main(String[] args) {
Thread[] syncs = new Thread[5];
SyncTest4 syncTest4 = new SyncTest4();
for (int i = 0; i < syncs.length; i++) {
syncs[i] = new Thread(syncTest4);
}
for(Thread sync : syncs){
sync.start();
}
}
}
class SyncTest4 implements Runnable {
public synchronized static void test() {
System.out.println(Thread.currentThread().getName() + "running...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "over...");
}
@Override
public void run() {
test();
}
}



