zoukankan      html  css  js  c++  java
  • 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啦。

  • 相关阅读:
    C语言编译多文件
    vs(visual studio 2019)恢复默认设置
    everything 有文件搜不到
    potplayer显示右侧插入列表消息
    ubuntu 关机、重启命令
    post&get请求总结
    C# string格式的日期时间字符串转为DateTime类型
    css position: absolute、relative详解
    在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
    ASP.NET获取客户端及服务器的信息
  • 原文地址:https://www.cnblogs.com/Cyning/p/3617873.html
Copyright © 2011-2022 走看看