在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

但是实际在使用过程你会发现一些令你迷惑的问题,就来看下吧下面的代码:

public class SeThread implements Runnable {

	private int i;

	@Override
public void run() {
for (; i < 20; i++) { System.out.println(Thread.currentThread().getName() + " i= "+ i); } } public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
if (i == 20) {
SeThread st = new SeThread();
new Thread(st, "线程1").start();
new Thread(st, "线程2").start();
}
}
} }

 

可以看到,st是一个Runnable接口实现类的对象,但是却被两个线程作为参数,啊啊。这个打印结果是什么玩意??

  看到这或许你已经猜到了,这个是两个Thread的外壳下居然是同一颗跳到的Runnable心,那么还是看下Thread的实现吧。

public
class Thread implements Runnable { public synchronized void start() { group.add(this); boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
} private native void start0(); @Override
public void run() {
if (target != null) {
target.run();
}
} //……
}

其实,Thread就是Runnable实现类,在调用start过程中,我们可以知道它实现调用的是一个start0()这个本地方法,这个从我们以前开发用的方法可知,肯定是在CPU资源分配过程中的某个时机调用了Thread的run()方法了,而run()方法实现的执行体就是传入的Runnable对象的runnable。

所以两个Thread的执行体,就是同一个runnale对象了,这个看上去是两个线程,可实际上只有一个执行体那就是st对象啦,打印结果肯定是如上图看到的那样了。

其实这个打印有两个0,可知线程未同步,我们可以在处理打印这个方法做个同步修饰synchronized,这样就可以正确的打印从0到99啦。

java的线程中的Runnable的更多相关文章

  1. Java子线程中的异常处理(通用)

    在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally ...代码块就可以了.那么,在并发情况下,比如在父线程中启动了子线程,如何正确捕获子线程中的异常,从而进行相 ...

  2. Java子线程中操作主线程Private级别数据

    两个类分别如下: <pre name="code" class="java">package Demo2; import java.util.*; ...

  3. 转:Java子线程中的异常处理(通用)

    引自:https://www.cnblogs.com/yangfanexp/p/7594557.html 在普通的单线程程序中,捕获异常只需要通过try ... catch ... finally . ...

  4. java 5线程中 Semaphore信号灯,CyclicBarrier类,CountDownLatch计数器以及Exchanger类使用

    先来讲解一下Semaphore信号灯的作用:  可以维护当前访问自身的线程个数,并提供了同步机制, 使用semaphore可以控制同时访问资源的线程个数 例如,实现一个文件允许的并发访问数. 请看下面 ...

  5. Java 多线程 ---- 线程中this与 Thread.currentThread()线程的区别

    总结起来一句话:在Thread中调用this其实就是调用Thread私有Runnable类型的target,target是Thread类的一个属性,而Thread.currentThread()是指新 ...

  6. JAVA 线程中的异常捕获

    在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked e ...

  7. Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别

    一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...

  8. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  9. JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)

    实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...

随机推荐

  1. How Tomcat Works(七)

    本文接下来介绍并分析servlet容器,servlet容器是用来处理请求servlet资源,并为web客户端填充response对象的模块. servlet容器是org.apache.catalina ...

  2. android 获取手机型号,本机电话号码,SDK版本以及firmwarw版本号(即系统版本号)

    Android开发平台中,可通过TelephonyManager 获取本机号码. TelephonyManager phoneMgr=(TelephonyManager)this.getSystemS ...

  3. zookeeper的安装和启动

    最近的手上一个项目要用到dubbo,顺便研究下zookeeper 1.下载 下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/,下载解压到D:\t ...

  4. ASP.NET中DesignMode属性

    参考:http://blog.sina.com.cn/s/blog_4c9da9b50100r4u7.html http://book.51cto.com/art/200902/108836.htm ...

  5. Slony-I 文摘

    http://www.onlamp.com/pub/a/onlamp/2004/11/18/slony.html  我特别喜欢这篇文章,就进行了转载和翻译. Introducing Slony by  ...

  6. js原生appendChild的bug

    appendChild 主要是用来追加节点 插入到最后 window.onload = function(){ var ul2 = document.getElementById('ul2'); va ...

  7. CodeForces 176A Trading Business 贪心

    Trading Business 题目连接: http://codeforces.com/problemset/problem/176/A Description To get money for a ...

  8. Codeforces Round #309 (Div. 2) A. Kyoya and Photobooks 字符串水题

    A. Kyoya and Photobooks Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...

  9. Codeforces Round #188 (Div. 2) A. Even Odds 水题

    A. Even Odds Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/318/problem/ ...

  10. java学习笔记(5)——内部类

    一.内部类 1,静态内部类 使用static修饰,声明在类体中 静态内部类中可以访问外部类的静态成员 2,成员内部类 声明在类体中,不使用static,具有类的成员特征,也就是,必须有类的实例才能 创 ...