线程、进程运行的五个状态:创建、就绪、运行、阻塞、中止。它们之间的关系的非常重要,是这几个方法的理论基础。
- join方法:
例如main线程中调用thread-0.join()方法。或者join(long mills)
result: 将main线程由运行态进入阻塞态,等待thread-0的执行完成或者一段时间后,重新进入就绪状态。
public class ThreadJoin extends Thread
{
public void run()
{
for (int i = 0; i < 100 ; i++ )
{
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args)throws Exception
{
// 启动子线程Thread-0
// new ThreadJoin().start();
for (int i = 0; i < 100 ; i++ ) //计数的是main线程
{
if (i == 20)
{
// 启动子线程 Thread-1
ThreadJoin jt = new ThreadJoin();
jt.start();
// main主线程调用了子线程.join()方法,main线程必须等jt执行结束才会向下执行
// 某个线程调用 "其他线程" 的join()——当前线程运行态到阻塞态 区别yield(运行状态到就绪状态)
jt.join();
//形式2 join(long millis) 子线程若干毫秒后main线程执行
}
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
-
2.yield 方法
例如: thread-0使用yield方法
result: 只是相当于重新分配一次cpu,重新进入就绪态(而非进入阻塞态)
//yield 将线程由运行态到就绪态,相当于重新分配了一次cpu
//如果线程优先级更高此yield无效
//sleep 方法更容易控制并发线程
public class Threadyield extends Thread
{
public void run()
{
for (int i = 0; i < 50 ; i++ )
{
System.out.println(getName() + " " + i);
// 当i等于20时,使用yield方法让当前线程让步
if (i == 20)
{
Thread.yield();
}
}
}
public static void main(String[] args)throws Exception
{
// 比较两条并发线程
Threadyield yt1 = new Threadyield();
// 将ty1线程设置成最高优先级
//yt1.setPriority(Thread.MAX_PRIORITY);
yt1.start();
Threadyield yt2 = new Threadyield();
// 将yt2线程设置成最低优先级
// yt2.setPriority(Thread.MIN_PRIORITY);
yt2.start();
}
}
-
3.priority set优先级方法
也涉及到了threadGroup概念,父线程创建的子线程默认权限、优先级相同。
getpriority setpriority
//更改线程优先级 setPriority
public class ThreadPriority extends Thread
{
// 定义一个有参数的构造器,用于创建线程时指定name
public ThreadPriority(String name)
{
super(name);
}
public void run()
{
for (int i = 0 ; i < 50 ; i++ )
{
System.out.println(getName() + ":" + getPriority() + " i值:" + i);
}
}
public static void main(String[] args)
{
// 改变主线程的优先级,所以main 线程创建的子线程默认优先级为6
Thread.currentThread().setPriority(6);
for (int i = 0 ; i < 300 ; i++ )
{
if (i == 10)
{
ThreadPriority low = new ThreadPriority("低级");
low.start();
System.out.println("创建之初的优先级:" + low.getPriority());
// 设置该线程为最低优先级
low.setPriority(Thread.MIN_PRIORITY);
}
if (i == 200)
{
ThreadPriority high = new ThreadPriority("高级");
high.start();
System.out.println("创建之初的优先级:" + high.getPriority());
// 设置该线程为最高优先级
high.setPriority(Thread.MAX_PRIORITY);
}
}
}
}
-
4.daemon 线程
例如: 将thread-0 设置为main线程的后台守护线程
//jvm垃圾回收线程 就是一个典型的后台线程
//前台线程死亡后,后台线程会自动死亡
//jvm垃圾回收线程 就是一个典型的后台线程
public class ThreadDaemon extends Thread
{
// 定义后台线程的线程执行体与普通线程没有任何区别
//我们需要它运行到1000
public void run()
{
for (int i = 0; i < 1000 ; i++ )
{
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args)
{
ThreadDaemon thread_t = new ThreadDaemon();
// 将此线程设置成后台线程
thread_t.setDaemon(true);
thread_t.start();
//先延迟10毫秒main线程,让thread-0有机会输出
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0 ; i < 10 ; i++ )
{
System.out.println(Thread.currentThread().getName() + " " + i);
}
// -----程序执行到此处,前台线程(main线程)结束------
// 后台线程也应该随之结束,不会输出到1000
}
}