博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基础---->多线程之Runnable(一)
阅读量:5213 次
发布时间:2019-06-14

本文共 4473 字,大约阅读时间需要 14 分钟。

  java线程的创建有两种方式,这里我们通过简单的实例来学习一下。一切都明明白白,但我们仍匆匆错过,因为你相信命运,因为我怀疑生活。

 

java中多线程的创建

一、通过继承Thread类来创建多线程

public class HelloThread extends Thread {    @Override    public void run() {        try {            TimeUnit.SECONDS.sleep(1);            System.out.println("Hello from a thread!");        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static void main(String[] args) throws InterruptedException {        HelloThread helloThread = new HelloThread();        helloThread.start();        System.out.println("In main thread.");    }}

运行的结果如下:

In main thread.Hello from a thread!

我们这里对Thread类的start的方法做一些说明,官方文档的说明:

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread. The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method). It is never legal(合法) to start a thread more than once(不止一次). In particular, a thread may not be restarted once it has completed execution. Throws:     IllegalThreadStateException - if the thread was already started

我们在上述例子的基础上,对上述的说明做一个代码的测试。在helloThread.start();代码的后面添加代码:

System.out.println(helloThread.getName());helloThread.start();

一次的运行结果如下所示,在添加代码的第二行(helloThread.start();)报的错误。

Exception in thread "main" java.lang.IllegalThreadStateExceptionThread-0    at java.lang.Thread.start(Thread.java:708)    at com.linux.huhx.thread.HelloThread.main(HelloThread.java:22)Hello from a thread!

如果在添加helloThread.start();之前让主线程睡眠3秒,也就是让先启动的helloThread线程执行完毕。我们再调用helloThread.start()启动线程。

TimeUnit.SECONDS.sleep(3);System.out.println(helloThread.getName());helloThread.start();

运行的结果如下:

Hello from a thread!Thread-0Exception in thread "main" java.lang.IllegalThreadStateException    at java.lang.Thread.start(Thread.java:708)    at com.linux.huhx.thread.HelloThread.main(HelloThread.java:22)

 

二、通过实现Runnable接口来创建多线程

public class HelloRunnable implements Runnable {    @Override    public void run() {        try {            System.out.println("Hello from a thread!");            TimeUnit.SECONDS.sleep(1);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        Thread thread = new Thread(new HelloRunnable());        thread.start();        System.out.println("In main method.");    }}

运行的结果如下:

In main method.Hello from a thread!

  这种使用实现HelloRunnable接口的方式是比较推崇的,因为java类中只能单继承可以多实现。现在看一下它的简单原理new Thread(new HelloRunnable())的源码如下:

public Thread(Runnable target) {    init(null, target, "Thread-" + nextThreadNum(), 0);}

init的方法是初始化线程的一些信息:

private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc, boolean inheritThreadLocals) {    if (name == null) {        throw new NullPointerException("name cannot be null");    }    this.name = name;    Thread parent = currentThread();    SecurityManager security = System.getSecurityManager();    if (g == null) {        if (security != null) {            g = security.getThreadGroup();        }        if (g == null) {            g = parent.getThreadGroup();        }    }    g.checkAccess();    if (security != null) {        if (isCCLOverridden(getClass())) {            security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);        }    }    g.addUnstarted();    this.group = g;    this.daemon = parent.isDaemon();    this.priority = parent.getPriority();    if (security == null || isCCLOverridden(parent.getClass()))        this.contextClassLoader = parent.getContextClassLoader();    else        this.contextClassLoader = parent.contextClassLoader;    this.inheritedAccessControlContext = acc != null ? acc : AccessController.getContext();    this.target = target;    setPriority(priority);    if (inheritThreadLocals && parent.inheritableThreadLocals != null)        this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);    this.stackSize = stackSize;    tid = nextThreadID();}

  最重要的一行代码就是this.target = target;设置了线程target为我们的Runnable对象。我们都知道thread.start()启动一个线程,实际是调用线程的run方法。现在我们看一下Thread类的run方法。

@Overridepublic void run() {    if (target != null) {        target.run();    }}

  可以看到是调用了target的run方法,在我们这里就是(HelloRunnable)。对于继承Thread的的情况来说,就拿上述的HelloThread来讲,它里面的target是空的。不过执行的run方法是HelloThread重写的run方法。所以不存在HelloThread中没有target就不会执行的情况。

 

友情链接

 

转载于:https://www.cnblogs.com/huhx/p/baseusejavathreadrunnable.html

你可能感兴趣的文章
Lexia 3 V48 Diagbox 软件安装指引
查看>>
时间管理
查看>>
刻意练习,逃离舒适区:怎么样成为一个高手
查看>>
limits.conf文件修改注意事项,限制文件描述符数和进程数
查看>>
WS调用的时候报错
查看>>
linux 命令大全
查看>>
命令模式
查看>>
897.Increasing Order Search Tree
查看>>
HTMLDiary
查看>>
2.JVM的参数配置
查看>>
iOS下获取用户当前位置的信息
查看>>
Ubuntu中安装(升级)GraphicsMagick
查看>>
防火墙
查看>>
css3动画animation
查看>>
eclipse安装wtp
查看>>
(转)C#中属性PropertyInfo的使用,Dictionary转为Model实例
查看>>
2017NOIP游记
查看>>
学习yii2.0框架阅读代码(二)
查看>>
Windows Apache2.4 配置https/SSL
查看>>
PHP常用魔术方法(__call魔术方法:)
查看>>