• 线程创建方式


    Java虚拟机的主线程,它从启动类main()方法开始运行。用户也可以创建自己的线程,它将和主线程并发运行。创建线程的两种方式:

      (1)继承java.lang.Thread类;

      (2)实现Runnable接口。

     1.扩展java.lang.Thread类,用户的线程只需要继承Thread类,覆盖Thread类的run()方法即可。

     实例:run()方法指定这个线程所执行的代码。

    public class Machine extends Thread {
        //重写Thread类的run()方法
        public void run(){
            for(int a=0;a<50;a++){
                System.out.println(currentThread().getName()+":"+a);
            }
            try {
                sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            Machine m=new Machine();    //创建第一个machine对象
            Machine m1=new Machine();   //创建第二个machine对象
            m.start();            //启动第一个machine线程,因为Machine类继承Thread类,重写了run()方法
            m1.start();            //启动第二个machine线程
         m.run();              //主线程执行第一个Machine对象的run()方法 } }

       1.1  上面,主线程执行main()方法时,会创建两个Machine对象,然后启动两个Machine线程。接着主线程开始执行第一个Machine对象的run()方法。在Java虚拟机中有三个线程并发执行Machine对象的run()方法。三个线程各自的方法栈中都有代表run()方法的栈帧,在这个帧中存放局部变量a,可见(3)每个线程都拥有自己的局部变量a,它们都从0增加到50。

       run()方法中currentThread().getName()相当于:

    Thread thread=new Thread(); //返回当前正在执行这行代码的线程的引用
    String name=thread.getName();  //获得线程的名字

      线程默认为Thread-0  Thread-1可以通过Thread类的setName()方法显式设置线程的名字。

      1.2 多个线程共享同一个对象的实例变量

    public class Machine extends Thread{
        private int a;
        public void run(){
            for(a=0;a<50;a++){
                System.out.println(currentThread().getName()+":"+a);
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            Machine m=new Machine();
            m.start();
            m.run();
        }
    }

        上面代码,主线程和Machine线程都会执行Machine对象的run()方法:主线程和Machine线程并发执行Machine对象的run()方法时,都会操纵同一个实例变量a,这两个线程轮流给变量a增加1.

    public class TestOne extends Thread{
        private int a;
        //重写Thread类的run()方法
        public void run(){
            for(a=0;a<30;a++){
                System.out.println(currentThread().getName()+":"+a);        
            }
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            TestOne t1=new TestOne();
            TestOne t2=new TestOne();
            t1.start();
            t2.start();
        }
    }

       以上代码,因为实例方法和静态方法的字节码都位于方法区,被所有线程共享。t1线程和t2线程分别执行t1对象和t2对象的run()方法,意味着t1执行run()方法时,会把run()方法中的变量a解析为t1对象的实例变量a,t2线程执行run()方法时,会把run()方法中的变量a解析为t2对象的实例变量a。所以,t1线程和t2线程分别操纵不同的实例变量a。各自输出0-29

     1.3 不要随便覆盖Thread类的start()方法

      随意覆盖,所有方法的调用都会变成主线程完成。假如一定要覆盖start()方法,那么应该先调用super.start()方法。

    1.4 一个线程只能被启动一次

    public static void main(String[] args) {
            TestOne t1=new TestOne();
            TestOne t2=t1;
            t1.start();
            t2.start();
    }

      如果将上面代码main部分改成这样,t2.start()会抛出java.lang.IllegalThreadStateException异常。

    2.实现Runnable接口

    public class Machine implements Runnable{
      privat int i=0; @Override
    public void run() { for(i=0;i<40;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { Machine m=new Machine(); Thread t1=new Thread(m); Thread t2=new Thread(m); t1.start(); t2.start(); } }

      如上,主线程创建了t1和t2两个线程对象。启动t1和t2线程将执行m变量所引用的Machine对象的run()方法。t1和t2共享同一个machine对象。因此执行run()方法时将操纵同一个实例变量i.

  • 相关阅读:
    Blob
    MySQL This function has none of DETERMINISTIC, NO SQL...错误1418 的原因分析及解决方法 (转)
    事务--存储过程
    JDBC-Mysql-编译预处理(占位符)
    socket
    GUI---深度复制
    串行化--深度复制
    RESTful理解
    django中文和时区的配置
    redis-server报错
  • 原文地址:https://www.cnblogs.com/taray/p/5380820.html
Copyright © 2020-2023  润新知