- 线程常用操作
- 线程的命名和取得
- 线程休眠
- 线程中断
- 线程强制运行
- 线程礼让
- 线程优先级
线程的命名和取得都是来源于Thread类中线程名称的操作
常用有一下三种操作
- 构造方法命名:public Thread(Runnalbe target,String name) ;
- setName()方法命名:public final void setName(String name);
- getName()方法取得名字:public final String getName();
范例:在run()方法中获取线程名称
class mythread implements Runable{
@Override
public void run{
System.out.println(Thrad.currentThread().getName());
}
}
public class ThreadDemo{
public static void main(String[] args) throws Exception{
mythread mt=new mythread();
new Thread(mt,"线程A").start();//设置了线程名字
new Thread(mt).start();//未设置线程名字
new Thread(mt,"线程B").start();//设置了线程名字
}
}
获取线程名称时,未命名线程会自动分配名称
接下来获取主线程名称
class mythread implements Runable{
@Override
public void run{
System.out.println(Thrad.currentThread().getName());
}
}
public class ThreadDemo{
public static void main(String[] args) throAws Exception{
mythread mt=new mythread();
new Thread(mt,"线程对象").start();//设置了线程名字
mt.run();//对象直接调用run()方法
}
}
获取主线程名称为main(主方法也是线程)
我们可以希望某个线程能够暂缓执行以方便观察运行状态
在进行休眠的时候有可能会产生在进行休眠的时候有可能会产生
中断异常“InterruptedException”,中断异常属于Exception的子类,证明该异常必须进行处理
休眠方法:
- 休眠:public static void sleep(long millis) throws InterruptedException;
- 休眠:public static void sleep(long mills,int nanos) throws InterruptedException;
范例:观察休眠处理(单个对象进行线程休眠处理)
public class ThreadDemo{
public static void main(String[] args) throws Exception{
new Thread(()->{
for(int x=0;x<10;x++)
{
System.out.println(Thread.currentThrad().getName()+",x="+x);
try{
Thread.sleep(1000);暂缓执行
}
catch(InterruptedException e){
e.printStackTrace();
}
}
},"线程对象").start();
}
}
在线程的启动上有线程后,当程序休眠再启动也有先后,就像接力比赛,接棒时当作休眠,休眠后每个人的运行速度是不相同的,这就造成了线程执行完毕的先后顺序也是不同的
范例:产生多个线程对象进行线程处理
public class ThreadDemo{
public static void main(String[] args) throws Exception{
Runnable run=()->{
for(int x=0;x<10;x++)
{
System.out.println(Thread.currentThrad().getName()+",x="+x);
try{
Thread.sleep(1000);暂缓执行
}
catch(InterruptedException e){
e.printStackTrace();
}
}
};
for(int num=0;num<5;num++)
{
new Thread(run,"执行线程"+num).start();
}
}
}
线程休眠要通过运行代码自己观察
线程中断在之前的线程休眠中发现里面提供有一个中断异常,这实际上证明线程休眠是可以被打断的,这种打断肯定是由其他线程完成的
在Thread类里面提供有线程处理方法
- 判断线程是否被中断:public boolean isInterrupted();
- 中断线程执行:public void interrupt();
范例:观察线程的中断处理
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread=new Thread(()->{
System.out.println("*****我需要休眠*****");
try {
Thread.sleep(10000);//休息10秒
System.out.println("***睡足了,可以去工作了***");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("休息被打断");
}
});
thread.start();//开始休息
Thread.sleep(1000);//先休息1秒钟
if(!thread.isInterrupted()) {//询问是否中断休息
//没有中断
thread.interrupt();//现在打断你的休息
}
}
}
正在执行的线程都是可以被中断的,中断的线程必须进行异常处理
当满足某些条件之后,某一个线程对象可以一直独占资源一直到线程结束
范例:观察一个没有强制执行的程序
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread=new Thread(()->{
for(int x=0;x<100;x++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++)
{
Thread.sleep(100);
System.out.println("霸道的main线程执行x="+x);
}
}
}
我们发现在子线程会和主线程抢占资源进行输出,接下来我们看看在利用了线程的强制执行后的运行状态
在Thread类里面提供有强制执行方法,join()方法
public final void join() throws InterruptedException
利用join()方法我们可以使线程强制执行独占资源
从强制执行抛出异常看出,强制执行也可以被中断
范例:强制执行程序
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread mainThread=new Thread().currentThread();//获取主线程
Thread thread=new Thread(()->{
for(int x=0;x<100;x++)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(x>3)
{
try {
mainThread.join();//霸道的线程开始执行
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++)
{
Thread.sleep(100);
System.out.println("霸道的main线程执行x="+x);
}
}
}
可以看出当下x>3后main()开始独占资源,当main()执行完成后其他线程才开始执行
在进行强制执行的时候一定要获取强制执行线程对象才可以进行join的操作
线程礼让在多线程中,可以先将资源让出去让别的线程先执行,线程的礼让可以用Thread中的方法
- 礼让方法:public static void yield();
范例:线程的礼让执行
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread=new Thread(()->{
for(int x=0;x<100;x++)
{
if(x%3==0)
{
Thread.yield();//玩耍的线程礼让了
System.out.println("****玩耍的线程礼让了*****");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行、x="+x);
}
},"玩耍的线程");
thread.start();
for(int x=0;x<100;x++)
{
Thread.sleep(100);
System.out.println("霸道的main线程执行x="+x);
}
}
}
每一次调用yield()都只会礼让一次当前的资源
从理论上讲线程的优先级越高越有可能先执行(越有可能先抢占到资源)在Thread类里面提供有如下的两个处理方法
- 设置优先级:public final void setPriority(int newPriority);
- 获取优先级:public final int getPriority();
在进行优先级定义的时候都是通过int型的数字来进行完成的,而对于此类数字的选择在Thread类里面就有定义 - 最高优先级:public static final int MAX_PRIORITY、10(优先级的值)
- 中等优先级:public static final int NORM_PRIORITY、5(优先级的值)
- 最低优先级:public static final int MIN_PRIORITY、1(优先级的值)
范例:没有设置优先级
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Runnable run=()->{
for(int x=0;x<10;x++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行");
}
};
Thread threadA=new Thread(run,"线程A对象");
Thread threadB=new Thread(run,"线程B对象");
Thread threadC=new Thread(run,"线程C对象");
threadA.start();
threadB.start();
threadC.start();
}
}
不同电脑效果不同,本人的是B优先执行
接下来看使用优先级后电脑执行的效果
范例:观察设置优先级后的效果
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Runnable run=()->{
for(int x=0;x<10;x++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行");
}
};
Thread threadA=new Thread(run,"线程A对象");
Thread threadB=new Thread(run,"线程B对象");
Thread threadC=new Thread(run,"线程C对象");
threadA.setPriority(Thread.MIN_PRIORITY);//把AB设置优先级最小
threadB.setPriority(Thread.MIN_PRIORITY);//把AB设置优先级最小
threadC.setPriority(Thread.MAX_PRIORITY);//把AB设置优先级最小
threadA.start();
threadB.start();
threadC.start();
}
}
提高有先级确实可以提高线程先执行的可能,但是并不是绝对先执行
补充:主方法是一个主线程,主线程的优先级是多少呢?
public class ThreadDemo {
public static void main(String[] args) throws Exception {
System.out.println(Thread.currentThread().getPriority());
}
}
发现主线程的优先级是5,只是中等优先级,同时这与我们默认的方法的优先级是相同的



