一. 线程初体验
java实现一个线程最基本就3种方式(其他的都是通过这几个衍生出来)
1.继承Thread类(实现了Runnable接口),重写run方法(Runnable的方法)
2.实现Runnable接口,重写run方法
3.实现Callable(函数式接口),重写call方法,有回调
方法1:
public class ThreadOne extends Thread {
@Override
public void run() {
System.out.println("当前线程是:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
System.out.println("主线程是:" + Thread.currentThread().getName());
new ThreadOne().start();
}
}
我们通过start启动一个新的线程,看start方法可以看到,会执行已和native方法(屏蔽jvm执行平台的差异),private native void start0(),用c++编写,最终会在回调我们重写的run方法,在方法2可以看到
方法2:
public class ThreadTwo implements Runnable {
@Override
public void run() {
System.out.println("Runnable当前线程是:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
System.out.println("Runnable主线程是:" + Thread.currentThread().getName());
new Thread(new ThreadTwo()).start();
}
}
执行runnable的方法
方法3:
public class ThreadThree implements Callable {
@Override
public Object call() throws Exception {
System.out.println("Callable当前线程是:" + Thread.currentThread().getName());
return "success";
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
System.out.println("Callable当前线程是:" + Thread.currentThread().getName());
//带执行结果的
Future future = executorService.submit(new ThreadThree());
future.get();
}
}
这里涉及线程池后面文章会详细讲。
二. 线程状态
通过看jdk1.8 Thread.State枚举类 线程有6个状态,其中图中Runnable可以人为的划分为Ready和Running
线程状态的转换如上图,各步骤触发的条件如下:
步骤1:new Thread.start()
步骤2:Thread.yield()会让出cpu,Running到Ready状态
步骤3:interrupt中断
步骤4:Object.wait(time),Object.join(time),Theaad.sleep(time),LockSupport.parkNanos(time); LockSupport.parkUntil(time);
步骤5:Object.wait(),Object.join(),LockSupport.park()
步骤6:synchronized
上面典型的演示下:
sleep后,timed_waiting状态
public class ThreadOne extends Thread {
@Override
public void run() {
System.out.println("当前线程是:" + Thread.currentThread().getName());
try {
sleep(2000);
System.out.println(Thread.currentThread().getName() +
"睡眠结束后状态是:" + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("主线程是:" + Thread.currentThread().getName());
ThreadOne threadOne = new ThreadOne();
threadOne.start();
State state1 = threadOne.getState();
System.out.println(threadOne.getName() + "初始状态是:" + state1);
try {
//主线程睡眠时间小于子线程
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadOne.getName() + "睡眠状态是:" + threadOne.getState());
}
}
join(join最终会调用Object.wait)后,通过打断点的方式,主线程进入waiting状态
public class ThreadOne extends Thread {
@Override
public void run() {
System.out.println("当前线程是:" + Thread.currentThread().getName());
try {
sleep(2000);
System.out.println();
sleep(2000);
System.out.println(Thread.currentThread().getName() +
"睡眠结束后状态是:" + Thread.currentThread().getState());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("主线程是:" + Thread.currentThread().getName());
ThreadOne threadOne = new ThreadOne();
threadOne.start();
threadOne.join();
System.out.println("结束了");
}
}
synchronized后,线程进入blocked状态
public class ThreadOne extends Thread {
private Object object;
ThreadOne(Object o) {
object = o;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "状态是:" + Thread.currentThread().getState());
synchronized (object) {
try {
//让其他线程获取不到锁
sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
System.out.println("主线程是:" + Thread.currentThread().getName());
Object object = new Object();
ThreadOne threadOne = new ThreadOne(object);
threadOne.start();
sleep(500);
ThreadOne threadTwo = new ThreadOne(object);
threadTwo.start();
sleep(500);
System.out.println(threadOne.getName() + "状态是:" +
threadOne.getState());
System.out.println(threadTwo.getName() + "状态是:" +
threadTwo.getState());
}
}