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.IllegalThreadStateException
Thread-
at java.lang.Thread.start(Thread.java:)
at com.linux.huhx.thread.HelloThread.main(HelloThread.java:)
Hello from a thread!

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

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

运行的结果如下:

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

二、通过实现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方法。

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

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

友情链接

最新文章

  1. 单选框的回显c:if
  2. MVC中使用WebMail 发送注册验证信息
  3. java获取本机IP地址
  4. php大力力 [003节]php在百度文库的几个基础教程mac环境下文本编辑工具
  5. Android——android:gravity 和 android:layout_Gravity
  6. 在Delphi7中JSON遍历节点不支持使用IN处理方法
  7. 用shell写个100以内的所有数字之和
  8. 详解C中volatile关键字
  9. Android布局自定义Shap圆形ImageView,可以单独设置背景与图片
  10. crm2011i创建nt类型字段
  11. ue4竖排文本显示
  12. Qt QGraphicsItem要点 积累
  13. oracle死锁的处理办法
  14. mysql 更新语句中加判断条件
  15. Python爬虫-01:爬虫的概念及分类
  16. statement对象与sql语句(新手)
  17. 学习笔记(3)——实验室集群WMS服务配置
  18. ES6学习笔记七:生成器与异步操作
  19. SQL SERVER 2005快捷键
  20. 仿LOL项目开发第六天

热门文章

  1. anroid 广播
  2. php BC高精确度函数库
  3. 用window调用kjb和ktr
  4. 关于Cocos2d-x中数据的存储提取和类型转换
  5. 仿教程 小爬虫抓取imooc数据
  6. php -- 取日期
  7. iOS 开发系列:CoreData Object 变成 Fault 的一种方式
  8. CentOS 6.5 下利用命令行截图及设置快捷键截图
  9. 3D游戏与计算机图形学中的数学方法-点线面
  10. html中可以自定义属性,,,妈的竟然才知道..