(4.1.21.2)Android Thread

  • 创建新线程的常用方式:

       1. 直接使用Thread创建 
           Thread thread = new Thread(); 
           thread.start(); 
      2. 扩展java.lang.Thread类 
           Thread类的定义public class Threadextends Object implements Runnable(){…} 
    扩展Thread类的实质其实也是实现Runnable接口,只不过Thread类继承了Object类方法 
      3. 实现Runnable接口

    具体代码:

      1. 扩展java.lang.Thread类 
    public class test3_4  extends Activity  { 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            MyThread myThread = new MyThread(); 
            myThread.start(); 
        } 
        class MyThread extends Thread{

             public void run() { 
                System.out.println("zz"); 
            }   
       } 
    }

    注:看见网上有人举这个例子 
            MyThread myThread = new MyThread(); 
            myThread.start(); 
            myThread.start(); 
            myThread.start(); 
    我在模拟器上测试了运行不过,不能得到预期结果。不知道为什么!runnable的也不行!

    2. 实现Runnable接口 
    public class test3_4  extends Activity { 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            MyThread myThread = new MyThread(); 
            new Thread(myThread).start(); 
        } 
        class MyThread implements Runnable{ 
            public void run() { 
                System.out.println("zz"); 
            }    
        } 
    }

    或者

    public class test3_4  extends Activity implements OnClickListener, Runnable{ 
         private Button button; 
         private TextView text; 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            button = (Button)findViewById(R.id.button); 
            text = (TextView)findViewById(R.id.text); 
            button.setOnClickListener(this); 
        }

        public void onClick(View v) { 
            Thread thread = new Thread(this); 
            thread.start(); 
        }

        public void run() { 
            System.out.println("zz"); 
        } 
    }

    经典实例:

    多个窗口一起卖火车票问题。假设有3个窗口同时售票,共有10张火车票代售。启动三个线程卖共同的10张票。

    1. 使用下面的代码试图实现功能

    public class test3_5  extends Activity implements OnClickListener{ 
         private Button button; 
         private TextView text; 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.main); 
            button = (Button)findViewById(R.id.button); 
            text = (TextView)findViewById(R.id.text); 
            button.setOnClickListener(this); 
        }

        public void onClick(View v) { 
            MyThread myThread1 = new MyThread(); 
            MyThread myThread2= new MyThread(); 
            MyThread myThread3 = new MyThread(); 
            myThread1.start(); 
            myThread2.start(); 
            myThread3.start(); 
        } 
        class MyThread extends Thread{ 
            private int tickets = 10; 
            public void run() { 
                for(int i = 0; i< 200; i++){ 
                    if(tickets > 0) 
                    { 
                        System.out.println(Thread.currentThread().getName() + "==>" + tickets--); 
                    } 
                } 
            } 
        } 
    }

    运行结果:

    05-11 08:24:09.426: INFO/System.out(6331): Thread-8==>10 
    05-11 08:24:09.457: INFO/System.out(6331): Thread-8==>9 
    05-11 08:24:09.526: INFO/System.out(6331): Thread-8==>8 
    05-11 08:24:09.548: INFO/System.out(6331): Thread-8==>7 
    05-11 08:24:09.556: INFO/System.out(6331): Thread-8==>6 
    05-11 08:24:09.556: INFO/System.out(6331): Thread-8==>5 
    05-11 08:24:09.576: INFO/System.out(6331): Thread-8==>4 
    05-11 08:24:09.597: INFO/System.out(6331): Thread-10==>10 
    05-11 08:24:09.606: INFO/System.out(6331): Thread-10==>9 
    05-11 08:24:09.606: INFO/System.out(6331): Thread-10==>8 
    05-11 08:24:09.648: INFO/System.out(6331): Thread-8==>3 
    05-11 08:24:09.656: INFO/System.out(6331): Thread-9==>10 
    05-11 08:24:09.656: INFO/System.out(6331): Thread-9==>9 
    05-11 08:24:09.666: INFO/System.out(6331): Thread-8==>2 
    05-11 08:24:09.666: INFO/System.out(6331): Thread-8==>1 
    05-11 08:24:09.686: INFO/System.out(6331): Thread-9==>8 
    05-11 08:24:09.686: INFO/System.out(6331): Thread-10==>7 
    05-11 08:24:09.686: INFO/System.out(6331): Thread-10==>6 
    05-11 08:24:09.737: INFO/System.out(6331): Thread-9==>7 
    05-11 08:24:09.746: INFO/System.out(6331): Thread-9==>6 
    05-11 08:24:09.746: INFO/System.out(6331): Thread-9==>5 
    05-11 08:24:09.766: INFO/System.out(6331): Thread-10==>5 
    05-11 08:24:09.776: INFO/System.out(6331): Thread-10==>4 
    05-11 08:24:09.776: INFO/System.out(6331): Thread-10==>3 
    05-11 08:24:09.776: INFO/System.out(6331): Thread-10==>2 
    05-11 08:24:09.846: INFO/System.out(6331): Thread-9==>4 
    05-11 08:24:09.846: INFO/System.out(6331): Thread-9==>3 
    05-11 08:24:09.846: INFO/System.out(6331): Thread-9==>2 
    05-11 08:24:09.886: INFO/System.out(6331): Thread-9==>1 
    05-11 08:24:09.886: INFO/System.out(6331): Thread-10==>1

    分析:

    运行结果与预期不一致,分析可以看出3个线程各种卖各自的10张票,而不是共同的10张票。

    在上面的代码中,只能保证:每个线程都将启动,每个线程都将运行直到完成。一系列线程以某种顺序启动并不意味着将按该顺序执行。对于任何一组启动的线程来说,调度程序不能保证其执行次序,持续时间也无法保证。

    2. 只修改onClick里面的代码,并分析运行结果

    public void onClick(View v) { 
        //实例化线程对象 
        MyThread myThread = new MyThread(); 
        new Thread(myThread, "窗口1").start(); 
        new Thread(myThread, "窗口2").start(); 
        new Thread(myThread, "窗口3").start(); 
    }

    运行结果:

    05-11 08:41:50.946: INFO/System.out(6790): 窗口2==>10 
    05-11 08:41:50.956: INFO/System.out(6790): 窗口2==>8 
    05-11 08:41:50.986: INFO/System.out(6790): 窗口1==>9 
    05-11 08:41:50.996: INFO/System.out(6790): 窗口1==>5 
    05-11 08:41:51.006: INFO/System.out(6790): 窗口1==>4 
    05-11 08:41:51.018: INFO/System.out(6790): 窗口2==>6 
    05-11 08:41:51.018: INFO/System.out(6790): 窗口2==>3 
    05-11 08:41:51.026: INFO/System.out(6790): 窗口2==>2 
    05-11 08:41:51.036: INFO/System.out(6790): 窗口1==>1 
    05-11 08:41:51.046: INFO/System.out(6790): 窗口3==>7

    分析:

    我认为此处3个窗口已经是在卖共同的10张票了,只不过由于没有进行线程同步才造成数据混乱。

    线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。

    3. 下面继续修改代码,验证我刚得猜测。

    public void onClick(View v) { 
        //实例化线程对象 
        MyThread myThread = new MyThread(); 
        new Thread(myThread, "窗口1").start(); 
        new Thread(myThread, "窗口2").start(); 
        new Thread(myThread, "窗口3").start(); 
    }

    class MyThread extends Thread{ 
        private int tickets = 10; 
        public void run() { 
            for(int i = 0; i< 200; i++){ 
                    sell(); 
            } 
        } 
        public synchronized  void sell(){ 
                if(tickets > 0) 
                { 
                    System.out.println(Thread.currentThread().getName() + "==>" + tickets--); 
                } 
        } 
    }

    运行结果:

    05-11 08:53:31.986: INFO/System.out(7116): 窗口1==>10 
    05-11 08:53:32.006: INFO/System.out(7116): 窗口1==>9 
    05-11 08:53:32.016: INFO/System.out(7116): 窗口1==>8 
    05-11 08:53:32.066: INFO/System.out(7116): 窗口1==>7 
    05-11 08:53:32.086: INFO/System.out(7116): 窗口1==>6 
    05-11 08:53:32.106: INFO/System.out(7116): 窗口1==>5 
    05-11 08:53:32.106: INFO/System.out(7116): 窗口1==>4 
    05-11 08:53:32.126: INFO/System.out(7116): 窗口1==>3 
    05-11 08:53:32.146: INFO/System.out(7116): 窗口1==>2 
    05-11 08:53:32.146: INFO/System.out(7116): 窗口1==>1

    分析:

    一个对象只有一个锁。所以,如果一个线程获得该锁,就没有其他线程可以获得锁,直到第一个线程释放(或返回)锁。这也意味着任何其他线程都不能进入该对象上的synchronized方法或代码块,直到该锁被释放。

    释放锁是指持锁线程退出了synchronized同步方法或代码块。

    上述代码没有Thread.sleep(10),换句话说线程一一直处于运行状态,没有释放锁,没有给其他线程运行的机会。

    4. 根据上述分析,修改代码如下:

    public void onClick(View v) { 
            //实例化线程对象 
            MyThread myThread = new MyThread(); 
            new Thread(myThread, "窗口1").start(); 
            new Thread(myThread, "窗口2").start(); 
            new Thread(myThread, "窗口3").start(); 
        } 
        class MyThread extends Thread{ 
            private int tickets = 10; 
            public void run() { 
                for(int i = 0; i< 200; i++){ 
                    try{ 
                        sell(); 
                        Thread.sleep(10); 
                    }catch (InterruptedException e) { 
                        System.out.println("我被打断了" + Thread.currentThread().getName()); 
                        e.printStackTrace(); 
                    }

                } 
            } 
            public synchronized  void sell(){ 
                    if(tickets > 0) 
                    { 
                        System.out.println(Thread.currentThread().getName() + "==>" + tickets--); 
                    } 
            } 
        }

    运行结果:

    05-11 09:17:07.496: INFO/System.out(7898): 窗口1==>10 
    05-11 09:17:07.528: INFO/System.out(7898): 窗口1==>9 
    05-11 09:17:07.546: INFO/System.out(7898): 窗口1==>8 
    05-11 09:17:07.577: INFO/System.out(7898): 窗口1==>7 
    05-11 09:17:07.626: INFO/System.out(7898): 窗口3==>6 
    05-11 09:17:07.626: INFO/System.out(7898): 窗口2==>5 
    05-11 09:17:07.636: INFO/System.out(7898): 窗口1==>4 
    05-11 09:17:07.646: INFO/System.out(7898): 窗口2==>3 
    05-11 09:17:07.646: INFO/System.out(7898): 窗口1==>2 
    05-11 09:17:07.656: INFO/System.out(7898): 窗口3==>1

    分析:

    此次得出的正是我们想要的结果!O(∩_∩)O~

    5. 使用实现Runnable接口的方法重新实现上述功能

    public void onClick(View v) { 
            //实例化线程对象 
            MyThread myThread = new MyThread(); 
            new Thread(myThread, "窗口1").start(); 
            new Thread(myThread, "窗口2").start(); 
            new Thread(myThread, "窗口3").start(); 
        } 
        class MyThread implements Runnable{ 
            private int tickets = 10; 
            public void run() { 
                for(int i = 0; i< 200; i++){ 
                    try{ 
                        sell(); 
                        Thread.sleep(10); 
                    }catch (InterruptedException e) { 
                        System.out.println("我被打断了" + Thread.currentThread().getName()); 
                        e.printStackTrace(); 
                    }

                } 
            } 
            public synchronized  void sell(){ 
                    if(tickets > 0) 
                    { 
                        System.out.println(Thread.currentThread().getName() + "==>" + tickets--); 
                    } 
            }

    关于线程的理解个人推荐一篇非常棒的文章,里面对java线程进行的详细的总结,仔细阅读必有收获!

    http://lavasoft.blog.51cto.com/62575/27069/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值