二.线程常见的方法

一.线程的调度

1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。
 
Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY
          线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY
          线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY
          分配给线程的默认优先级,取值为5。
 
Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。
 
每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。

二.上篇文章提到线程有五个状态,其中有一个阻塞状态,到底哪几种情况会导致线程阻塞呢?

先看一下这个图:



考虑一下三个方面,不考虑IO阻塞的情况:

睡眠;

等待;

因为需要一个对象的锁定而被阻塞。

这就涉及到线程常用的几个方法

1.睡眠(线程的静态方法)

Thread.sleep(long millis)Thread.sleep(long millis, int nanos)静态方法强制当前正在执行的线程休眠(暂停执行),使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。

睡眠的位置:放在run()方法之内。

public class ThreadSleep implements Runnable{

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println(i);
            try {
                //睡眠一秒
                Thread.sleep(1000);//参数以毫秒计算
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //每隔10个输出一个字符串
            if(i%10==0){
                System.out.println("-------"+i);
            }
        }
    }
    public static void main(String[] args) {
        ThreadSleep ts=new ThreadSleep();
        Thread thread=new Thread(ts);
        thread.start();
    }

}
输出结果:(省略一部分)



2、等待:

Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法,行为等价于调用 wait(0) 一样。
调用wait()notify()系列方法时,当前线程必须拥有此对象监视器(即对象锁)。
 synchronized (obj) {
    
while (<condition does not hold>)
    obj.wait();
    .
.. // Perform action appropriate to condition
         }
    此方法只应由作为此对象监视器的所有者的线程来调用。

3.让步(线程的静态方法)

Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。
public class ThreadYield extends Thread{
	
	public ThreadYield(String name) {
		super(name);
	}

	@SuppressWarnings("static-access")
	@Override
	public void run() {
		for (int i = 0; i < 15; i++) {
			System.out.println(this.getName()+"------"+i);
			//当i为10时,线程就会把cpu时间让掉,让其他或者自己的线程执行
			if(i==10){
				this.yield();
			}
			
		}
	}
	public static void main(String[] args) {
		ThreadYield ty1=new ThreadYield("小明");
		ThreadYield ty2=new ThreadYield("小红");
		ty1.start();
		ty2.start();
	}
}
运行一下:

再次运行一下:

可以看出来:(实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。)

4、加入(线程的非静态方法)

join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。

public class ThreadJoin implements Runnable{
    
    private static int count=5;
    public static int getCount() {
        return count;
    }
    public static void setCount(int count) {
        ThreadJoin.count = count;
    }
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            count++;
        }
            
    }
    public static void main(String[] args) {
        ThreadJoin join1=new ThreadJoin();
        Thread t1=new Thread(join1);
        t1.start();
        System.out.println(count);
        
    }

}
运行一下:

为什么结果没有变呢?这是因为main方法本身也是一个线程,当主线程main方法执行完毕时,线程t1有可能正在启动,或者还没能运行完,总之就是晚于主线程的执行。
这时候join()方法就可以控制运行的顺序。
public static void main(String[] args) {
		ThreadJoin join1=new ThreadJoin();
		Thread t1=new Thread(join1);
		t1.start();
		try {
			t1.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(count);
		
	}
这时候结果就是10了。











 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值