多线程一

目录

一 实现多线程的三种方式

二 线程的生命周期 

三 线程的开启,中断,复位 

四 yield与join方法的区别


一 实现多线程的三种方式

继承Thread类

实现Runnable接口

实现Callable接口

public class DothreadDemo extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
//        new DothreadDemo().start();
        // 由于 Thread继承了Runnable接口所以 可以使用下面方法启动线程 
        new Thread(new DothreadDemo()).start();
    }
}
public
class Thread implements Runnable {

二 线程的生命周期 

线程一共有六种状态        在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;
    }

 

三 线程的开启,中断,复位 

1 线程的启动为什么是start

    如果直接调用线程的run()方法 是什么效果? ---》和调用普通的对象成员方法一样

   通过start()方法开启线程 --》调用native方法  private native void start0();---》jvm 调用 操作系统分配线程

2 线程的中断

    不能调用 stop()方法去关闭线程,stop() 相当于 innux 系统中的kill -9,  无论线程是否执行完毕都会强制杀死线程,对于正在执行的业务代码,这种操作会出现不可控的风险。

使用 interrupt()和 isInterrupted() 方法  

 再hotspot代码中 有个标识位  _interrupted  默认为false

interrup()  会调用  native方法  private native void interrupt0();   将一个标识位  _interrupted 改为 true

isInterrupted() 判断标识位 _interrupted 是否为 false

public class InterruptDemo {

    private static int i;

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {//默认是false
                i++;
            }
            System.out.println("i:" + i);
        });
        thread.start();

        TimeUnit.SECONDS.sleep(1);
        thread.interrupt();//改成true
    }

}
 /**
     * Tests whether this thread has been interrupted.  The <i>interrupted
     * status</i> of the thread is unaffected by this method.
     *
     * <p>A thread interruption ignored because a thread was not alive
     * at the time of the interrupt will be reflected by this method
     * returning false.
     *
     * @return  <code>true</code> if this thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see     #interrupted()
     * @revised 6.0
     */
    public boolean isInterrupted() {
        return isInterrupted(false);
    }

    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);

3 线程的中断和线程的复位

   使线程复位有两种方式  Thread.interrupted();    和InterruptedException

Thread.interrupted();   

public class ThreadResetDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("before:" + Thread.currentThread().isInterrupted());
                    Thread.interrupted();//将 _isinterrupted   复位设置成false
                    System.out.println("after:" + Thread.currentThread().isInterrupted());
                }
            }

        });
        thread.start();

        TimeUnit.SECONDS.sleep(1);
        thread.interrupt();//改成true
    }
}

Thread.interrupted() 是属于当前线程的,是当前线程对外界中断信号的回应,表示我已经收到了中断信号,但不会马上中断自己,具体什么时候中断由自己决定。所以它先将_interrupted 复位。

InterruptedException

public class ThreadReset2Demo {
    private static int i;
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {//默认是false
                try {
                    TimeUnit.SECONDS.sleep(10);
                    System.out.println("demo");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("i:" + i);
        });
        thread.start();

        TimeUnit.SECONDS.sleep(1);
        thread.interrupt();//改成true

        System.out.println(thread.isInterrupted());
    }
}
false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at java.lang.Thread.sleep(Thread.java:340)
	at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
	at com.vincent.teng.projectservice.daily.dosomething.ThreadReset2Demo.lambda$main$0(ThreadReset2Demo.java:16)
	at java.lang.Thread.run(Thread.java:748)
demo
demo
demo

对于 sleep(),wait(),join() 等阻塞方法,都有对应的方法结束  notify()  notifyAll()等

如果线程运行调用阻塞方法之后  sleep(),wait(),join() 线程处于 waiting/time_waiting状态,这时如果调用 thread.interrupted() 将标识位

_interrupted改为true, 这些阻塞方法不会停止运行,而thread将会抛出 InterruptedException 。InterruptedException会将thread复位

_interrupted改为false。thread继续运行。如果想安全退出线程可以在catch语句块中进行相应处理 如 break;

 

四 yield与join方法的区别

https://www.jianshu.com/p/873f799153fb

yield()方法:暂停当前正在执行的线程对象,并执行其他线程。

yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

jion()方法:线程实例的join()方法可以使得一个线程在另一个线程结束后再执行,即也就是说使得当前线程可以阻塞其他线程执行;

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。

比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

join()方法使用示例

线程实例的join()方法可以使得一个线程在另一个线程结束后再执行。如果join()方法在一个线程实例上调用,当前运行着的线程将阻塞直到这个线程实例完成了执行。例如下面代码所示,t将阻塞t1知道t执行完毕后在执行t1;

在join()方法内可以设定超时,使得join()方法在超时后无效。当超时时,主方法和任务线程申请运行的时候是平等的。然而,当涉及sleep时,join()方法依靠操作系统计,所以你不应该假定join()方法将会等待你指定的时间。

像sleep,join通过抛出InterruptedException对中断做出回应。

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执行完毕后t1执行
      t.start(); // Line 15
      t.join(); // Line 16
      t1.start();
   }
}
 
Output:
 
First task started
Sleeping for 2 seconds
First task completed
Second task completed



 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值