JAVA线程浅析(二)

多线程浅析(二)
       JAVA中多线程是抢占式的运行方式,哪个线程抢占到时间片,哪个线程就先运行。而线程调度是按照某种原则选择一个线程使它占有处理器运行,线程调度是操作系统的核心,线程调度策略的优劣直接影响操作系统的性能。线程调度有相对调度和绝对调度。
1.相对调度
(1)Thread.setPriority()设置线程优先级—线程优先级有10级,越大越优先(优先级越高只是说该线程抢占的资源的几率会更大,并不绝对)

(2)Thread.sleep()让当前线程睡眠一段时间—对当前线程操作,是静态方法,除非被中断而提前恢复执行,否则线程在这段时间不会执行
注意:在引入同步锁时,sleep()方法不会释放锁,但会把处理器资源释放出来

(3)Thread.interrupt()—调用一个被暂停线程的interrupt()方法,可以变相起到唤醒暂停线程的作用,所以能够用来作为强制唤醒线程的技术

(4)Thread.yield()—放弃当前线程抢占到的机会,然后和其他同优先级的线程再抢一次(这里只是放弃当前的机会,有可能再抢一次的时候又是该线程抢到)
相对调度代码演示:

public class S`chedualDemo {
    public static void main(String[] args) {

        MyRun r1=new MyRun(1);
        Thread t1=new Thread(r1);

        MyRun r2=new MyRun(2);
        Thread t2=new Thread(r2);

        //1、相对调度
        //设置线程优先级,优先级从1~10,越大越优先
        t1.setPriority(10);
        t2.setPriority(1);

        t1.start();//启动线程
        t2.start();//启动线程

        try {
            Thread.sleep(1000);//线程睡眠
            t2.interrupt();//强制唤醒,当前线程会进入运行态--相对调度
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class MyRun implements Runnable{

    private int num;
    public MyRun(int num){
        this.num=num;
    }

    @Override
    public void run() {
        if(num==1){
            //这里Thread.sleep()让当前线程睡眠,但是但存在锁时,不会释放锁,只会把内存资源释放出去
            //Thread.sleep(10);
            Thread.yield();//相当于在同优先级的线程内部再抢一次
        }
        for(int i=0;i<10;i++){
                //System.out.println(Thread.currentThread().getName()+":"+i);
                //Thread.currentThread().getName()
            System.out.println(num+":"+i);
        }
    }
}

2.绝对调度
(1)join()方法—调用某线程的该方法,把该线程与当前合并,即把当前线程运行结束,再恢复当前线程的运行。(相当于类中的调用方法)
(2)wait()方法—当前线程进入等待池中
(3)notify()或notifyAll()方法—唤醒等待池中一个或全部线程
注意:wait()和notify()方法必须对应使用;当线程拥有同步锁时,wait()方法既会释放处理器资源同时也会释放锁。

public class MyStack {
    private char[] ch=new char[6];
    private int idx=0;
    //无论是锁方法还是同步块的锁,只要是同一把对象锁,都可以锁---效果是一样的
    public void push(char c){
        synchronized (this) {//拿锁
            ch[idx]=c;
            System.out.println("push:"+c);
            idx++;
            this.notify();
        }//还锁
    }
    public synchronized char pop(){
        if(idx==0){
            try {
                this.wait();//wait()方法会把锁释放出来,sleep()方法不会释放锁,但两者都会释放CPU资源
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        idx--;
        System.out.println("pop:"+ch[idx]);
        return ch[idx];
    }
}
----------
public class PopThread extends Thread{

    private MyStack ms=new MyStack();
    public PopThread(MyStack ms){
        this.ms=ms;
    }
    @Override
    public void run() {
        for(int i=97;i<103;i++){
            ms.pop();
        }
    }
}
----------
public class PushThread extends Thread{
    MyStack ms=new MyStack();
    public PushThread(MyStack ms){
        this.ms=ms;
    }
    @Override
    public void run() {
        for(int i=97;i<103;i++){
            ms.push((char)i);
        }
    }
}
----------
public class Client {
    public static void main(String[] args) {
        MyStack ms=new MyStack();
        Thread push=new PushThread(ms);
        Thread pop=new PopThread(ms);
        push.start();
        pop.start();
    }
}

3.线程相关概念
(1)线程的创建和线程的启动不相同:在一个线程对象没有调用start()方法时,这个线程对象并没有真正执行;而线程对象在启动之前或者退出之后都是存在的,都可以控制和获取线程的相关信息。
(2)线程的结束:

  • 自然结束–达到run()方法的末尾
  • 线程抛出一个未捕获到的Exception或Error
  • 调用已经过时的stop()方法

(3)守护线程:在Java程序运行的时候,存在一些隐藏线程,这些线程随着程序启动而启动,在程序运行期间一直捕捉符合条件的处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值