Java线程

1、线程的创建

(1)继承Thread类

public class A extends Thread{
    public static void main(String[] args) {
        A a=new A();
        a.start();

        A a1=new A();
        a1.start();
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for(int i=0;i<=50;i++){
            System.out.println("输出为:"+getName()+"***"+i);
        }
    }
}

部分输出结果如下所示(执行顺序的不确定的):

输出为:Thread-0***43

输出为:Thread-1***21
输出为:Thread-0***44
输出为:Thread-1***22
输出为:Thread-0***45
输出为:Thread-1***23
输出为:Thread-0***46
输出为:Thread-1***24
输出为:Thread-0***47
输出为:Thread-1***25
输出为:Thread-1***26
输出为:Thread-0***48

(2)实现Runnable接口

public class B implements Runnable{
    public static void main(String[] args) {
        B b=new B();
        Thread thread=new Thread(b);
        B b1=new B();
        Thread thread1=new Thread(b1);
        thread.start();
        thread1.start();
    }
    @Override
    public void run() {
        for(int i=0;i<=100;i++){
            System.out.println("输出为:"+Thread.currentThread().getName()+"***"+i);
        }
    }
}

部分输出结果如下所示:

输出为:Thread-0***64

输出为:Thread-1***9
输出为:Thread-1***10
输出为:Thread-1***11
输出为:Thread-0***65
输出为:Thread-1***12
输出为:Thread-1***13
输出为:Thread-1***14
输出为:Thread-1***15

Thread类实际上也是实现了Runnable接口

2、线程状态

(1)新建状态:新创建了一个线程对象,还没有调用start()方法。

(2)就绪状态:当线程有资格运行,但调度程序还没有把它选为运行线程时线程所处的状态。当调用start()方法时,进入就绪状态;在线程运行之后或者从阻塞、等待或睡眠状态回来后也返回到就绪状态。

(3)执行状态:线程调度程序从可运行池中选择一个线程作为当前线程时所处的状态。此时正在执行run()方法。

(4)阻塞状态:由于某种原因放弃CPU使用权,暂时停止运行。阻塞状态有以下三种:

a、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
b、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
c、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状。

(5)死亡状态:当run()方法执行完毕或因异常退出run()方法,此线程结束,不能再调用start()方法。

下面是Thread类中定义的状态:

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }
3、线程调度

(1)优先级:

每一个线程都有一个表示优先级的值,在任意时刻如果有一个线程拥有比当前线程更高的优先级,它抢占低优先级线程的时间片,中断当前线程,开始新的线程。

Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
  /**
     * The minimum priority that a thread can have.
     */
    public final static int MIN_PRIORITY = 1;

   /**
     * The default priority that is assigned to a thread.
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * The maximum priority that a thread can have.
     */
    public final static int MAX_PRIORITY = 10;
Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。
    /**
     * Changes the priority of this thread.
     * <p>
     * First the <code>checkAccess</code> method of this thread is called
     * with no arguments. This may result in throwing a
     * <code>SecurityException</code>.
     * <p>
     * Otherwise, the priority of this thread is set to the smaller of
     * the specified <code>newPriority</code> and the maximum permitted
     * priority of the thread's thread group.
     *
     * @param newPriority priority to set this thread to
     * @exception  IllegalArgumentException  If the priority is not in the
     *               range <code>MIN_PRIORITY</code> to
     *               <code>MAX_PRIORITY</code>.
     * @exception  SecurityException  if the current thread cannot modify
     *               this thread.
     * @see        #getPriority
     * @see        #checkAccess()
     * @see        #getThreadGroup()
     * @see        #MAX_PRIORITY
     * @see        #MIN_PRIORITY
     * @see        ThreadGroup#getMaxPriority()
     */
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }

    /**
     * Returns this thread's priority.
     *
     * @return  this thread's priority.
     * @see     #setPriority
     */
    public final int getPriority() {
        return priority;
    }
每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。

(2)线程睡眠:

让当前线程睡眠有两个方法sleep(long millis)和sleep(long millis,int nanos)

/**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds, subject to
     * the precision and accuracy of system timers and schedulers. The thread
     * does not lose ownership of any monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static native void sleep(long millis) throws InterruptedException;

    /**
     * Causes the currently executing thread to sleep (temporarily cease
     * execution) for the specified number of milliseconds plus the specified
     * number of nanoseconds, subject to the precision and accuracy of system
     * timers and schedulers. The thread does not lose ownership of any
     * monitors.
     *
     * @param  millis
     *         the length of time to sleep in milliseconds
     *
     * @param  nanos
     *         {@code 0-999999} additional nanoseconds to sleep
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative, or the value of
     *          {@code nanos} is not in the range {@code 0-999999}
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }

线程睡眠到期自动苏醒,并返回到就绪状态,不是运行状态。sleep()中指定的时间是线程不会运行的最短时间。因此,sleep()方法不能保证该线程睡眠到期后就开始执行;sleep()是静态方法,只能控制当前正在运行的线程。
(3)线程等待
Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object类中的方法。
sleep()和wait()的区别:
a.sleep()是Thread类的方法,wait()是Object类的方法
b.sleep()不释放锁,wait()释放锁进入等待此对象的等待锁定池
c.sleep()指定睡眠时间,到期后自动回复,wait()只有此对象发出notify()或notifyAll()才能解除wait()状态(notify并不释放锁,只是告诉此对象可以参与锁的竞争了,但不是马上得到锁,因为锁有可能在别人手里还没有释放)

(4)线程让步

Thread.yield()方法,暂停当前正在执行的线程,使同优先级的线程有执行的机会。

Yield是一个静态的原生(native)方法Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。

yield不能保证使得当前正在运行的线程迅速转换到可运行的状态它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态

(5)线程加入
使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。
(7)sleep()和yield()的区别
        sleep()和yield()的区别):sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
        sleep 方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,yield 方法使当前线程让出 CPU 占有权,但让出的时间是不可设定的。实际上,yield()方法对应了如下操作:先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把 CPU  的占有权交给此线程,否则,继续运行原来的线程。所以yield()方法称为“退让”,它把运行机会让给了同等优先级的其他线程
       另外,sleep 方法允许较低优先级的线程获得运行机会,但 yield()  方法执行时,当前线程仍处在可运行状态,所以,不可能让出较低优先级的线程些时获得 CPU 占有权。在一个运行系统中,如果较高优先级的线程没有调用 sleep 方法,又没有受到 I\O 阻塞,那么,较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。 
4、线程组和线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值