1、抢占式线程
效率高可防止单一线程长时间占用cpu2、在单核cpu中,宏观上同时执行,微观上顺序执行。
初始状态–就绪状态–运行状态–终止状态 此外还有限期等待(sleep(n))–无限期等待join()–阻塞状态(synchronized) 请看下图: 但是在JDK5之后,就绪状态和运行状态统称Runnable
具体的状态我们可以通过getState()方法看到。
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 */ 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. * 调用join方法后其他线程进入waitting状态 */ 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> * 调用sleep方法后其他线程进入timed_waitting状态 */ TIMED_WAITING, /** * Thread state for a terminated thread. * The thread has completed execution. * 线程终止状态 */ TERMINATED; }在MyThread 类中有一个main方法,在执行main方法的时候会开启一个主线程来执行,在执行过程中有开启了子线程来执行myThread. 从以上代码中执行结果会出现主线程的子线程交替打印的情况 但是如果你想先执行myThread,在执行myThread1,最后打印主线程的话,你只需要加上这样一段代码就可以了 myThread.join(); myThread1.join(); 注意这时候就需要抛异常了throws InterruptedException
以上就是实现多线程的三种方式,但是要着重说一下实现Callable这种方式。 根据代码可以看出来,实现Callable后不能直接把对象给Thread对象,而是要经过FutureTask 包装后才能交给Thread。再仔细一点你就会发现实现Callable接口还需要抛出异常。
通过以上代码我们可以总结一下三种创建线程方式的区别:
1、实现线程方式大体可分为两类,一类是继承,一类是接口实现。 2、接口实现可以避免单继承的局限性。 3、Runnable要实现的方法是run()方法,Callable()要实现的方法是call()方法。 4、Callable任务执行完毕后会有返回值,而Runnable是没有返回值的。 5、call()方法需要抛异常,而run()方法不需要抛异常。 6、Callable对象需要交给FutureTask对象包装后才能交给Thread开启线程,而Runnable可以直接交给Thread。 7、Callable执行完毕后可以通过futureTask获取线程执行结果。