• java的线程中的Runnable


                      在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接口实现类的对象,但是却被两个线程作为参数,啊啊。这个打印结果是什么玩意??

    BaiduShurufa_2014-3-22_17-33-33

      看到这或许你已经猜到了,这个是两个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啦。

  • 相关阅读:
    Servlet的生命周期
    HTTP协议简单记录
    Tomcat和JavaWeb目录和流程
    02 html 表格表单
    01 初识HTML
    Python 利用pywin32批量将doc转换成docx再读取成一行存入excel
    power bi 数据红绿灯详细用法
    Linux和Windows启动后台程序
    MySQL导出数据字典
    适用于渗透测试不同阶段的工具收集整理
  • 原文地址:https://www.cnblogs.com/Cyning/p/3617873.html
Copyright © 2020-2023  润新知