线程<二> 线程创建及Thread生命周期

开启线程的方法;

1.new Thread(xx).start();
2.线程池:

实现线程任务的方法:

1.不带返回值:实现Runnable类run(),
2.实现带返回值的任务:RunnableFuture,代表子类:FutureTask

线程生命周期(状态)

public enum State {
1.NEW   //新建,未开始执行
2.RUNNABLE   //正在执行,但是可能等待processor(处理器)资源
3.BLOCKED   // 阻塞状态,等待获取监视器锁monitor lock,以便后面进入同步方法 或 调用object wait之后重新进入同步方法。 
4.WAITING   // 一直等待的线程会是WAITING状态,无限期等待其他线程执行的线程持有的状态
* 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>

5.TIMED_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>

6.TERMINATED //线程执行完毕或中断,线程退出
/**
 * Thread state for a terminated thread.
 * The thread has completed execution.
 */
}

重点api

1.join 让线程暂停 阻塞线程,使用了object的wait(0),等待唤醒

Causes the current thread to wait until either another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object, or a
     * specified amount of time has elapsed.

使用场景:主线程等待子线程执行完毕。

public class JoinExample
{
   public static void main(String[] args) throws InterruptedException
   {
      Thread t = new Thread(new Runnable()
         {
            public void run()
            {
               System.out.println("First task started");
               System.out.println("Sleeping for 2 seconds");
               try
               {
                  Thread.sleep(2000);
               } catch (InterruptedException e)
               {
                  e.printStackTrace();
               }
               System.out.println("First task completed");
            }
         });
      Thread t1 = new Thread(new Runnable()
         {
            public void run()
            {
               System.out.println("Second task completed");
            }
         });
      t.start(); 
      t.join(); 
      t1.start();
   }
}

2.Thread.yield() 非阻塞,使用场景:消费者生产者轮流执行。

  • Yield是一个静态的原生(native)方法
  • Yield告诉当前正在执行的线程把运行机会交给线程池中拥有相同优先级的线程。
  • Yield不能保证使得当前正在运行的线程迅速转换到可运行的状态
  • 它仅能使一个线程从运行状态转到可运行状态,而不是等待或阻塞状态
public class YieldExample
{
   public static void main(String[] args)
   {
      Thread producer = new Producer();
      Thread consumer = new Consumer();
 
      producer.setPriority(Thread.MIN_PRIORITY); //Min Priority
      consumer.setPriority(Thread.MAX_PRIORITY); //Max Priority
 
      producer.start();
      consumer.start();
   }
}
 
class Producer extends Thread
{
   public void run()
   {
      for (int i = 0; i < 5; i++)
      {
         System.out.println("I am Producer : Produced Item " + i);
         Thread.yield();
      }
   }
}
 
class Consumer extends Thread
{
   public void run()
   {
      for (int i = 0; i < 5; i++)
      {
         System.out.println("I am Consumer : Consumed Item " + i);
         Thread.yield();
      }
   }
}

\\添加Thread.yield();会让消费者和生产者轮流执行

wait()和sleep()区别

sleep :使当前执行的线程在指定的毫秒数内休眠(暂时停止执行),这取决于系统计时器和调度程序的精度和准确性。The thread does not lose ownership of any monitors.

wait:object方法,只能由其他线程notify或notifyall,会导致丢弃监视器。
线程必须先持有监视器,线程释放监视器,等待其他线程唤醒。

wait重载方法:(3个)
wait()
wait(long millis)
wait(long millis, int nanos)
下面两个表示等待多长时间,自己唤醒。

注意:调用obj.wait方法需要注意的是,当前线程必须获取到了obj的Monitor,才能去调用其wait方法,即wait必须放在同步方法或同步代码块中。(调用的是obj.wait(),而不是Thread.currentThread.wait())

monitor就是实现锁的方式。
entermonitor就是获得某个对象的lock(owner是当前线程)
leavemonitor就是释放某个对象的lock

Monitor的概念

Java虚拟机给每个对象和class字节码都设置了一个监听器Monitor,用于检测并发代码的重入,同时在Object类中还提供了notify和wait方法来对线程进行控制。

java通过synchronized关键字实现线程同步来获取对象的Monitor。synchronized同步分为以下两种方式:

静态方法和非静态方法synchronized的区别

  public synchronized void set() {
      
    }
  public static synchronized void set() {
  
    }

分析:
1.synchronized分别修饰了非静态方法和静态方法。
2.非静态方法,需要获取当前对象this的Monitor,获取后,其他需要获取该对象的Monitor的线程会被堵塞。
3.静态方法,需要获取该类字节码的Monitor(因为static方法不属于任何对象,而是属于类的方法),获取后,其他需要获取字节码的Monitor的线程会被堵塞。

thread.setDaemon(True)

特点:当所有线程为Daemon线程,jvm退出。

The Java Virtual Machine exits when the only threads running are all daemon threads

resume()是恢复suspend()的,suspend容易死锁所以废弃。

线程面试题:https://www.cnblogs.com/dolphin0520/p/3958019.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    胜浩_ae28阅读 10,537评论 0 23
  •   一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺...
    OmaiMoon阅读 5,632评论 0 12
  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    小徐andorid阅读 7,851评论 3 53
  • 温伯格还有很多妙趣横生的观点,比如: • 所有的问题都是人的问题,解决问题的第一步是理解人的感受。 • 你要是在意...
    上古天真2018阅读 851评论 0 0
  • 蒋勋 蒋勋﹙1947年-﹚,台湾知名画家、诗人与作家。福建长乐人。生于古都西安,战后举家移居台湾。自小成长于台北大...
    凡式善姐阅读 3,633评论 0 1