精华内容
下载资源
问答
  • java创建线程两种方式及区别

    千次阅读 2018-07-24 18:35:47
    本文将介绍创建线程两种方式,示例代码在下面,复制粘贴即可 继承Thread类方式和实现Runnable接口方式 区别:由于在开发的过程中,很多的类都会用到继承的方式,如果采用继承的方式会让各个类之间的关系变得错综...

    本文将介绍创建线程的两种方式,示例代码在下面,复制粘贴即可

    继承Thread类方式和实现Runnable接口方式

    区别:由于在开发的过程中,很多的类都会用到继承的方式,如果采用继承的方式会让各个类之间的关系变得错综复杂

    使得程序的可读性变差,所以在开发当中一般都用实现接口的方式,而且实现接口的方式还可以共享资源,共享资源的

    示例将在以后列出。

    /*
     * 创建线程的第一种方式:继承方式
     * 1.定义线程类,继承Thread类
     * 2.覆盖其中的run方法,并且run方法得用public修饰,否则系统会报错
     * 3.在主函数中创建线程对象
     * 4.调用线程对象的start方法
     */
    class xiancheng extends Thread//第一步
    {
        public void run() //第二步
        {
            for(int x=0;x<60;x++) 
            {
                System.out.println("1");
            }
        }
    }
    
    public class Test1 {
    
        public static void main(String[] args) 
        {
            xiancheng t=new xiancheng();//第三步
            t.start();//第四步
            for(int x=0;x<500;x++) 
            {
                System.out.println("2");
            }
        }
    
    }
    /*
     * 创建线程的第二种方式:实现接口
     * 1.定义线程类并实现Runnable接口
     * 2.覆盖Runnable中的run方法
     * 3.创建Runnable的子类线程对象
     * 4.将创建的子类对象作为参数传给Thread类的构造函数中
     * 5.调用start方法开启线程
     */
    class xiancheng1 implements Runnable//第一步
    {
        public void run() //第二步
        {
            for(int x=0;x<60;x++) 
            {
                System.out.println("1");
            }
        }
    }
    public class Test2 {
    
        public static void main(String[] args) 
        {
            xiancheng1 t=new xiancheng1();//第三步
            Thread t1=new Thread(t);//第四步
            t1.start();//第五步
            for(int x=0;x<500;x++) //主线程
            {
                System.out.println("2");
            }
        }
    
    }
    
    

     

    展开全文
  • 多线程之创建线程两种方式

    万次阅读 多人点赞 2018-05-29 00:33:56
    彩蛋: ...言归正传,今晚准备详细记录一下线程创建两种方式以及这两种方式的优缺点及适应的情况等等。 多进程:。。。 多线程:在一个应用程序中,多个顺序流同时执行。(线程:顺序执行的代...

    彩蛋:

    朕是小白,朕近段时间准备学一下有关线程方面的知识。(下面写的东西是我对线程的一些理解)

    今天是2018年5月28号,朕准备每天更新一篇博客来激励自己一直学习,不要间断,毕竟是位又懒自制力又差的家伙,哈哈哈!

    言归正传,今晚准备详细记录一下线程创建的两种方式以及这两种方式的优缺点及适应的情况等等。

    多进程:。。。

    多线程:在一个应用程序中,有多个顺序流同时执行。(线程:顺序执行的代码)

    创建线程有两种方式:

    一,(目标类来)继承Thread类,重写run方法来创建自己的线程。调用start函数就开始执行线程代码昂发啦!

    从Thread类派生一个子类,并创建子类的对象。

    子类应该重写Thread类的run方法,写入需要在新线程中执行的语句段。

    调用start方法来启动新线程,自动进入run方法。

    举例:在新线程中实现计算某个整数的阶乘的过程:

    package multi_thread;
    
    public class FactorialThreadTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		System.out.println("main thread starts");
    		FactorialThread thread = new FactorialThread(10);
    		thread.start();
    		System.out.println("main thread ends");
    	}
    }
    
    class FactorialThread extends Thread{
    	private int num;
    	public FactorialThread(int num) {
    		this.num = num;
    	}
    	public void run() {
    		int i = num;
    		int result = 1;
    		System.out.println("new thread started");
    		while(i>0) {
    			result*=i;
    			i--;
    		}
    		System.out.println("The factorial of "+num+" is "+result);
    		System.out.println("new thread ends");
    	}
    }

     

    运行结果:

     

    备注:factorial(阶乘)
    main thread starts
    main thread ends
    new thread started
    The factorial of 10 is 3628800
    new thread ends
    

    注:这里之所以要另外写一个主线程(public static void main(String[] args))是为了想说明创建的新线程并不是start()后就立即执行的。它其实也需要CPU来进行调度,轮到它了它才会被执行。通过运行结果我们可以看出。

    通过继承Thread类来创建线程大致流程就是上面这样。

    下面我想补充一些个人感觉很有用的知识(如果急着看另一种创建线程的方式,请往下翻~~~):

    Thread类常用的API方法,整理如下:

     

    名称说明
    public Thread()构造一个新的线程对象(Thread类的构造函数),默认名为Thread-n,n是从0开始递增的整数
    public Thread(Runnable target)构造一个新的线程对象,以一个实现Runnable接口的类的对象为参数,默认名为Thread-n,n是从0开始递增的整数(哈哈哈,从此处构造函数可以看出创建线程的两种不同方式,处处点题,我真机智!)
    public Thread(String name)构造一个线程对象,并同时指定线程名
    public static Thread currentThread()返回一个当前正在运行的线程对象
    public static void yield()使当前线程对象暂停,允许别的线程开始运行(注:yield:屈服)
    public static void sleep(long millis)使当前线程暂停运行指定毫秒数,但此线程并不失去已获得的锁
    public void start()启动线程,JVM将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程
    public void run()Thread的子类应该重写此方法,内容应为该线程应执行的任务
    public final void stop()停止线程运行,释放该线程占用的对象锁
    public void interrupt()中断此线程
    public final void join()如果启动了线程A,调用join方法将等待线程A死亡才能继续执行当前线程
    public final void join(long millis)如果此前启动了线程A,调用join方法将等待指定毫秒数或线程A死亡才能继续执行当前线程
    设置线程优先级
    public final void setPriority( int newPriority)设置线程优先级
    public final void setDaemon(Boolean on)设置是否为后台线程,如果当前运行线程均为后台线程则JVM停止运行。这个方法必须在start()方法前使用(注:daemon:后台程序)
    public final void checkAccess()判断当前线程是否有权力修改调用此方法的线程
    public void setName(String name)更改本线程的名称为指定参数
    public final boolean isAlive()测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回true

     

    二,写一个来实现Runnable接口,在初始化一个Thread类或者Thread子类的线程对象的时候 ,把该类的对象作为参数传递给那个线程对象。(其中由该类提供run方法)。

     

    Runnable接口:只有一个run()方法

    以实现Runnable接口的类的对象为参数建立新的线程

    还是举这个例子:在新线程中实现计算某个整数的阶乘的过程:

    package multi_thread;
    
    public class FactorialThreadTest_Runnable {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		System.out.println("main thread starts");
    		FactorialThreadRunnable t = new FactorialThreadRunnable(10);
    		new Thread(t).start();
    		System.out.println("new thread started, main thread ends");
    	}
    }
    
    class FactorialThreadRunnable implements Runnable{
    	private int num;
    	public FactorialThreadRunnable(int num) {
    		this.num = num;
    	}
    	public void run() {
    		int i = num;
    		int result = 1;
    		while(i>0) {
    			result*=i;
    			i--;
    		}
    		System.out.println("The factorial of "+num+" is "+result);
    		System.out.println("new thread ends");
    	}
    }

     

    运行结果:

     

    main thread starts
    new thread started, main thread ends
    The factorial of 10 is 3628800
    new thread ends
    

    再举一个使用Runnable接口实现上面多线程的例子:

    package multi_thread;
    
    public class ThreadSleepTester_Runnable {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		TestThread_Runnable thread1 = new TestThread_Runnable();
    		TestThread_Runnable thread2 = new TestThread_Runnable();
    		TestThread_Runnable thread3 = new TestThread_Runnable();
    		System.out.println("Starting threads");
    		new Thread(thread1,"Thread1").start();
    		new Thread(thread2,"Thread2").start();
    		new Thread(thread3,"Thread3").start();
    		System.out.println("Threads started,main ends");
    	}
    
    }
    
    class TestThread_Runnable implements Runnable{
    	private int sleepTime;
    	public TestThread_Runnable() {
    		sleepTime=(int)(Math.random()*6000);
    	}
    	public void run() {
    		try {
    			System.out.println(Thread.currentThread().getName()+" going to sleep for "+sleepTime);
    			Thread.sleep(sleepTime);
    		}
    		catch(InterruptedException e){};
    		System.out.println(Thread.currentThread().getName()+" finished");
    	}
    }

    运行结果:

    Starting threads
    Threads started,main ends
    Thread1 going to sleep for 5924
    Thread3 going to sleep for 2385
    Thread2 going to sleep for 2112
    Thread2 finished
    Thread3 finished
    Thread1 finished
    

    通过实现Runnable接口来创建线程大致流程就是上面这样。

     

    接下来我们要思考一个问题:创建线程的两种方式各有其优缺点:

    直接继承Thread类:

    优点:编写简单,直接继承,重写run方法。

    缺点:由于Java的单继承机制,不能再继承其他类了

    使用Runnable接口:

    优点有两个:一,可以继承其他类。Java不支持多继承,如果已经继承了某个基类,便需要实现Runnable接口来生成多线程。

    二,可以将CPU,代码和数据分开,形成清晰的模型,便于多个线程共享资源。

    其他的优缺点应该很好理解,但对于第二个(二,可以将CPU,代码和数据分开,形成清晰的模型,便于多个线程共享资源)优点,还是举个例子来说明比较好!

    通过实现Runnable接口为啥多个线程就可以共享数据等资源呢???

    package multi_thread;
    
    public class ShareTargetTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		TestThread_Runnable thread = new TestThread_Runnable();
    		System.out.println("Starting threads");
    		new Thread(thread,"Thread1").start();
    		new Thread(thread,"Thread2").start();
    		new Thread(thread,"Thread3").start();
    		System.out.println("Threads started,main ends");
    	}
    
    }
    class TestThread_Runnable implements Runnable{
    	private int sleepTime;
    	public TestThread_Runnable() {
    		sleepTime=(int)(Math.random()*6000);
    	}
    	public void run() {
    		try {
    			System.out.println(Thread.currentThread().getName()+" going to sleep for "+sleepTime);
    			Thread.sleep(sleepTime);
    		}
    		catch(InterruptedException e){};
    		System.out.println(Thread.currentThread().getName()+" finished");
    	}
    }

    运行结果:

    Starting threads
    Threads started,main ends
    Thread1 going to sleep for 4422
    Thread2 going to sleep for 4422
    Thread3 going to sleep for 4422
    Thread2 finished
    Thread1 finished
    Thread3 finished
    

    Thread1、Thread2和Thread3同时结束。(你运行一下看看就知道啦!)

    这里为啥Thread1、Thread2和Thread3休眠时间是一样的呢?好奇怪!(emmmm,寡人还是不故弄玄虚了。。。)

    原因是:你创建3个新线程传给Thread的参数是一毛一样滴,所以那3个新线程就共享了一个对象里的数据(sleepTime)啊,所以就是一样的!

    		TestThread_Runnable thread = new TestThread_Runnable();
    		new Thread(thread,"Thread1").start();
    		new Thread(thread,"Thread2").start();
    		new Thread(thread,"Thread3").start();

    扶朕起来,朕还可以再举一个例子:

    用三个线程模拟三个售票口,总共出售10张票。(注:这三个线程应该共享10张票的数据,因为总共就10张票,三个进程一起来销售)

    package multi_thread;
    
    public class sellTicketsTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		sellTickets t = new sellTickets();
    		new Thread(t,"Thread1").start();
    		new Thread(t,"Thread2").start();
    		new Thread(t,"Thread3").start();
    		
    	}
    }
    
    class sellTickets implements Runnable{
    	private int tickets = 10;
    	public void run() {
    		while(tickets>0) {
    			System.out.println(Thread.currentThread().getName()+" is selling ticket "+tickets--);
    		}
    	}
    }

    运行结果:

    Thread1 is selling ticket 10
    Thread3 is selling ticket 8
    Thread2 is selling ticket 9
    Thread3 is selling ticket 6
    Thread3 is selling ticket 4
    Thread3 is selling ticket 3
    Thread3 is selling ticket 2
    Thread3 is selling ticket 1
    Thread1 is selling ticket 7
    Thread2 is selling ticket 5
    

    哈哈哈,看完运行结果你就明白我滴意思了吧!

    在这个例子中,创建了3 个线程,每个线程调用的是同一个sellTickets对象t中的run()方法,访问的也是同一个对象t中的变量tickets。

    但是,如果是通过创建Thread类的子类来模拟售票过程,再创建3个新线程,则每个线程都有各自的方法和变量,虽然方法是相同的,但确是各有10张票,结果就会是每个线程都卖出了10张票,总共卖出了30张票,与原意就不符了!!!

    (个人感觉线程间的数据共享挺重要的,也挺有意思的)

    但是,上面代码运行多次后,会发现也会出现一些问题,比如某一个线程卖出第0张票的情况,比如两个不同的线程卖出同一张票的情况等等……没有保证线程的安全,具体见下:

    public class sellTicketsTester {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            sellTickets t = new sellTickets();
            new Thread(t,"Thread1").start();
            new Thread(t,"Thread2").start();
            new Thread(t,"Thread3").start();
            new Thread(t,"Thread4").start();
            new Thread(t,"Thread5").start();
            new Thread(t,"Thread6").start();
            new Thread(t,"Thread7").start();
    
        }
    }
    
    class sellTickets implements Runnable{
        private int tickets = 10;
        public void run() {
            while(tickets>0) {
                System.out.println(Thread.currentThread().getName()+" is selling ticket "+tickets--);
            }
        }
    }

    运行结果见下:

    Thread2 is selling ticket 10
    Thread2 is selling ticket 9
    Thread2 is selling ticket 8
    Thread2 is selling ticket 7
    Thread2 is selling ticket 6
    Thread2 is selling ticket 5
    Thread2 is selling ticket 4
    Thread2 is selling ticket 3
    Thread2 is selling ticket 2
    Thread2 is selling ticket 1
    Thread1 is selling ticket 0
    Thread3 is selling ticket 10
    Thread1 is selling ticket 10
    Thread2 is selling ticket 9
    Thread1 is selling ticket 7
    Thread3 is selling ticket 8
    Thread1 is selling ticket 5
    Thread2 is selling ticket 6
    Thread1 is selling ticket 3
    Thread3 is selling ticket 4
    Thread1 is selling ticket 1
    Thread2 is selling ticket 2

     为了保证线程安全,应该使用同步方法。

    1、在run方法前面加synchronized关键字

    public class sellTicketsTester {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            sellTickets t = new sellTickets();
            new Thread(t,"Thread1").start();
            new Thread(t,"Thread2").start();
            new Thread(t,"Thread3").start();
            new Thread(t,"Thread4").start();
            new Thread(t,"Thread5").start();
            new Thread(t,"Thread6").start();
            new Thread(t,"Thread7").start();
    
        }
    }
    
    class sellTickets implements Runnable{
        private int tickets = 10;
        public synchronized void run() {
            while(tickets>0) {
                System.out.println(Thread.currentThread().getName()+" is selling ticket "+tickets--);
            }
        }
    }

    2、同步代码块

    public class sellTicketsTester {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            sellTickets t = new sellTickets();
            new Thread(t,"Thread1").start();
            new Thread(t,"Thread2").start();
            new Thread(t,"Thread3").start();
            new Thread(t,"Thread4").start();
            new Thread(t,"Thread5").start();
            new Thread(t,"Thread6").start();
            new Thread(t,"Thread7").start();
    
        }
    }
    
    class sellTickets implements Runnable{
        private int tickets = 10;
        public  void run() {
            synchronized (this){
                while(tickets>0) {
                    System.out.println(Thread.currentThread().getName()+" is selling ticket "+tickets--);
                }
            }
        }
    }

    我还想补充一下线程有关的其他知识:

    一、线程休眠:(调用sleep方法)

    比如之前写的程序:

    package multi_thread;
    
    public class FactorialThreadTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		System.out.println("main thread starts");
    		FactorialThread thread = new FactorialThread(10);
    		thread.start();
    		System.out.println("main thread ends");
    	}
    }
    
    class FactorialThread extends Thread{
    	private int num;
    	public FactorialThread(int num) {
    		this.num = num;
    	}
    	public void run() {
    		int i = num;
    		int result = 1;
    		System.out.println("new thread started");
    		while(i>0) {
    			result*=i;
    			i--;
    		}
    		System.out.println("The factorial of "+num+" is "+result);
    		System.out.println("new thread ends");
    	}
    }
    

    运行结果:

     

    备注:factorial(阶乘)
    main thread starts
    main thread ends
    new thread started
    The factorial of 10 is 3628800
    new thread ends

     

    现在我让主线程休眠一毫秒,运行结果就会发生改变了哦,因为主线程休眠了一毫秒!

     

    package multi_thread;
    
    public class FactorialThreadTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		System.out.println("main thread starts");
    		FactorialThread thread = new FactorialThread(10);
    		thread.start();
    		try { Thread.sleep(1);}
    		catch(Exception e) {};
    		System.out.println("main thread ends");
    	}
    }
    
    class FactorialThread extends Thread{
    	private int num;
    	public FactorialThread(int num) {
    		this.num = num;
    	}
    	public void run() {
    		int i = num;
    		int result = 1;
    		System.out.println("new thread started");
    		while(i>0) {
    			result*=i;
    			i--;
    		}
    		System.out.println("The factorial of "+num+" is "+result);
    		System.out.println("new thread ends");
    	}
    }

    与上一个程序不同的是我只添加了红色标记的语句,运行结果见下:

    main thread starts
    new thread started
    The factorial of 10 is 3628800
    new thread ends
    main thread ends

    新线程结束后main线程才结束。

    多个线程休眠的情况见下:

    package multi_thread;
    
    public class ThreadSleepTester {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		TestThread thread1 = new TestThread("Thread1");
    		TestThread thread2 = new TestThread("Thread2");
    		TestThread thread3 = new TestThread("Thread3");
    		System.out.println("Starting threads");
    		thread1.start();
    		thread2.start();
    		thread3.start();
    		System.out.println("Threads started,main ends");
    	}
    }
    	
    	class TestThread extends Thread{
    		private int sleepTime;
    		public TestThread(String name) {
    			super(name);
    			sleepTime=(int)(Math.random()*6000);
    		}
    		public void run() {
    			try {
    				System.out.println(getName()+" going to sleep for "+sleepTime);
    				Thread.sleep(sleepTime);
    			}
    			catch(InterruptedException e){};
    			System.out.println(getName()+" finished");
    		}
    }

    备注:Math.random()产生0~1之间的随机数。

    Thread.sleep(sleepTime),其中sleepTime的单位是毫秒!

    运行结果见下:

    Starting threads
    Threads started,main ends
    Thread1 going to sleep for 5492
    Thread2 going to sleep for 1295
    Thread3 going to sleep for 3126
    Thread2 finished
    Thread3 finished
    Thread1 finished

     

    由于线程1休眠时间最长,所以最后结束;线程2休眠时间最短,所以最先结束。

     

    每次运行,都会随机产生不同的休眠时间,所以其实每次运行的结果都不相同!

    结尾也有彩蛋,嘻嘻:

    eclipse变量名如何实现一改全改呢?(个人感觉还是很有用的小技巧)

    双击选择要改的变量名,右键下拉菜单选择refactor重构选项,选择rename,然后就输入自己需要改成的名字,回车,搞定!

     

    展开全文
  • java创建线程常用的两种方式

    千次阅读 2019-01-29 14:47:32
    一、继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代 表了线程要完成的任务。因此把run()方法称为执行体。 (2)创建Thread子类的实例,即创建了线程对象。 (3)调用...

    一、继承Thread类创建线程类
    (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代 表了线程要完成的任务。因此把run()方法称为执行体。
    (2)创建Thread子类的实例,即创建了线程对象。
    (3)调用线程对象的start()方法来启动该线程。

    二、通过Runnable接口创建线程类
    (1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体是该线程的线程执行体。
    (2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
    (3)调用线程对象的start()方法来启动该线程。

    创建线程方式的对比:
    继承Thread类的方式创建多线程
    优势:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
    劣势是:线程类已经继承了Thread类,所以不能再继承其他父类。

    实现Runnable接口的方式创建多线程
    优势是:线程类只是实现了Runnable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,适合多个相同线程来处理同一份资源的情况。
    劣势是:编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
     

    展开全文
  • 创建线程两种方式区别

    千次阅读 2017-02-01 12:49:29
    Java提供了线程类Thread来创建线程的程序...要产生一个线程有两种方法: ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法。  ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法。 下面

    Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线程,有两种方法:

    ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法。 
    ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法。

    下面就从几个例子来具体列出两种方式的区别

    第一种方式:继承Thread类

    实现步骤:

    1.自定义类继承Thread 

    2.覆盖Thread中的run()方法

    3.创建该类的对象,调用start()方法,开启线程并调用run方法

    简单实例:

    class MyThread extends Thread{  
        public void run(){  
            for (int i = 0; i < 100; i++){  
                System.out.println("MyThread.run()..."+i);  
            }   /*单条线程运行一百次*/
        }  
    }  
    public class test1{  
        public static void main (String[] args){  
            MyThread a = new MyThread();  
            a.start();  
            for (int j = 0; j < 100; j++){  
                System.out.println("test1.main()----"+j);  
            }  
        }  
    }  
    
    第二种方式:实现Runnable接口

    实现步骤:

    1.定义一个实现Runnable接口的类

    2.覆盖run方法

    3.创建该类对象,并以该类对象为参数创建Thread类的对象,从而创建了一个线程

    4.调用start方法,开启线程并调用run方法。

    简单实例:

    class MyThread implements Runnable{  
        public void run (){  
            for (int i = 0; i < 50; i++){  
                System.out.println("MyThread.run()..."+i);  
            }                       /*每条线程运行50次,共200次*/
        }  
    }  
    public class test1{  
        public static void main (String[] args){  
            MyThread a = new MyThread();  
            Thread a1 = new Thread(a);  
            Thread a2 = new Thread(a);  
            Thread a3 = new Thread(a);  
            Thread a4 = new Thread(a);  
      
            a1.start();  
            a2.start();  
            a3.start();  
            a4.start();  
        }  
    }

    从上面两个例子看,除了多一个步骤外两种方式区别并不大 那么为什么通常都使用第二种方式呢 我们来看第三个例子

    public class test1{
        public static void main(String [] args){
            MyThread m=new MyThread();
            Thread t1=new Thread(m,"Thread 1");
            Thread t2=new Thread(m,"Thread 2");
            Thread t3=new Thread(m,"Thread 3");
            t1.start();         /*共运行一百次,  三条线程哪条抢到资源就运行哪条  */
            t2.start();
            t3.start();
        }
    }
    class MyThread implements Runnable{
        private int i=0;
        public void run(){
            while(i<100){
                i++;
            	System.out.println(i+"  MyThread.run "+Thread.currentThread().getName());
            }
        }
    }

    从这个例子我们可以看出,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的。

    实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。

    总结:

    采用继承Thread类方式:
    (1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
    (2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
    采用实现Runnable接口方式:
    (1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相 同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
    (2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

    展开全文
  • java 创建线程的三种方式、创建线程池的四种方式

    万次阅读 多人点赞 2019-02-23 21:01:44
    java创建线程的三种方式: 继承Thread类创建线程类 实现Runnable接口 通过Callable和Future创建线程 java创建线程池的四种方式: newCachedThreadPool 创建一个可缓存的线程池,如果线程池长度超过处理...
  • 创建和启动线程两种方式

    万次阅读 多人点赞 2016-10-07 10:52:48
    方式1:继承Thread类 步骤: 1):定义一个类A继承于java.lang.Thread类. 2):在A类中覆盖Thread类中的run方法. ...4):在main方法(线程)中,创建线程对象,并启动线程. (1)创建线程类对象: A类 a = new A类();
  • Android创建线程两种方式及比较

    万次阅读 2018-06-05 21:06:43
    一、Android创建线程方式通常为以下两种:  Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个...
  • 线程对象创建后,即进入新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable) 当调用线程对象的start()方法时,线程即进入就绪状态。处于就绪状态的线程只是说明此线程已经做好准备,随时等待CPU调度...
  • Qt 线程创建两种方式

    千次阅读 2018-08-30 10:38:26
    方法一:继承QThread老式方法 ...start()启动线程,线程会自动调用run()虚函数;run不可直接调用; #ifndef MYTHREAD_H #define MYTHREAD_H #include &lt;QThread&gt; class myThread: p...
  • 创建线程的三种方式优缺点

    千次阅读 2018-09-21 16:48:49
    Java使用Thread类代表...一、继承Thread类创建线程类 1.重写run方法。该run()方法的方法体就代表了线程需要完成的任务。 2.创建Thread子类的实例。 3.调用线程对象的start()方法来启动该线程。 public...
  • java中创建线程的4种方式

    千次阅读 2019-04-25 16:00:23
    java线程创建方式有几种?这种问题在面试中经常被问到,你可能心里马上反映出两种方式(实现Runnable、继承Thread),当你把这两种叙述给面试官听后,面试官会觉得你该掌握的知识已经有了,但是仅仅而已。如果你还说...
  • java中线程两种创建方式与比较

    千次阅读 2018-06-07 21:25:47
    下面讨论java中创建线程两种方式和之间的区别: 1. Runna接口 声明如下: public interface Runnable { public abstract void run(); } 这个接口只有一个run()方法,也就是线程的执行方法,一个线程对象必须实现...
  • java创建线程的四种方式及其区别

    千次阅读 2019-04-26 18:35:25
    java创建多线程如下四种方式: 继承Thread类创建线程 实现Runnable接口创建线程 使用Callable和Future创建线程 使用线程池创建(使用java.util.concurrent.Executor接口) 下面分别介绍这四创建多线程的方式...
  • 创建线程池有哪种方式

    万次阅读 2019-08-30 10:24:23
    Executors目前提供了5不同的线程池创建配置: 1、newCachedThreadPool(),它是用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;...
  • java以下四创建多线程的方式: 1:继承Thread类创建线程 2:实现Runnable接口创建线程 3:使用Callable和FutureTask创建线程 4:使用线程池,例如用Executor框架创建线程 DEMO代码: package thread; ...
  • 线程创建的四种方式

    万次阅读 多人点赞 2018-03-30 14:34:14
    Java可以用四种方式创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线程 3)使用Callable和Future创建线程 4)使用线程池例如用Executor框架 下面让我们分别来看看这四种创建线程的...
  • 第一种方式:继承Thread类 步骤:1、定义类继承Thread 2、覆写Thread类的run方法。...该线程有两个作用:启动线程,调用run方法。 代码示例: class Test extends Thread { //private String name; Te...
  • 创建线程两种方式Thread与Runnable 一、简要说明 创建线程两种方式,一是继承Thread类,二是实现Runnable接口,最后都是依据Thread类的构造方法实例化出一个线程对象,调用线程对象的start()方法,就可以通知...
  • JAVA多线程的三种创建方式

    万次阅读 多人点赞 2019-03-03 16:24:47
    一、概述 在JAVA中,用Thread类代表线程,所有线程对象,都必须是Thread类或者Thread类子类的实例。每个线程的任务就是执行...2.1第一,通过继承Thread类创建线程类 通过继承Thread类来创建并启动多线程的步骤...
  • 两种创建线程方式

    千次阅读 2020-11-20 11:37:38
    重写run方法,创建线程对象,调用static开启线程 子类继承Thread具备多线程能力 启动线程:子类对象.static 不建议使用:避免OOP单继承局限性 package com.zl.thread; /* 多线程:创造多个..
  • Qt创建线程两种方法

    万次阅读 多人点赞 2017-12-25 15:33:54
    Qt有两种线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。 Qt4.8之前都是使用继承QThread的run这种方法,但是Qt4.8之后,Qt官方建议使用第二种方法。两种方法...
  • 线程实现的两种方式及区别

    千次阅读 2018-12-03 13:10:47
    一、两种实现方式 继承Thread类,并重写run函数 实现Runnable接口,并重写run函数 因为Java是单继承的,用实现Runnable接口的方法创建对象可以避免Java单继承机制带来的局限。应尽可能使用实现Runnable接口的方式来...
  • 匿名内部类创建线程两种方式

    万次阅读 2017-02-26 17:32:48
    我们知道多线程的实现有两种方式,一种是继承Thread类,另一种是实现Runnable接口,然后再重写run方法,我们在普通的创建线程中,显然是比较麻烦的,那么没有一个算是简单的方法呢?今天小钱就给大家介绍使用匿名...
  • Java创建线程的8种方式

    万次阅读 多人点赞 2018-07-21 21:16:51
    Java创建启动线程的多种方式 1、继承Thread类,重写run()方法 2、实现Runnable接口,重写run() 3、匿名内部类的方式 4、带返回值的线程(实现implements Callable&lt;返回值类型&gt;)————以上3...
  • Java创建线程种方式: 1. 继承Thread类; 2. 实现Runnable接口; 3. 实现Callable接口,实例化FutureTask类; 4. 创建线程池(以下用Executor框架实现) 说明:这四种方式都潜移默化都用到了Thread类(表示线程),...
  • 【Window】创建线程的3种方式

    千次阅读 2018-11-01 12:43:41
    线程有挂起状态、执行状态、阻塞状态和等待状态。 下面分别介绍: 挂起状态:线程创建后并没有直接执行或是调用函数挂起了线程。被挂起了的线程没有执行的能力,只有调用启动函数了之后才能执行。 执行状态:在线程...
  • Java创建线程的四种方式

    万次阅读 多人点赞 2018-07-28 22:10:16
    一个线程调用 次start()方法将会抛出线程状态异常,也就是的start()只可以被调用一次   b.native生明的方法只有方法名,没有方法体。是本地方法,不是抽象方法,而是调用c语言方法  registerNative()方法包含了...
  • 创建线程的几种方式

    千次阅读 2018-08-27 15:48:35
    一般方法,Thread,Runnable,Callable,使用Executor框架来创建线程池。 Runnable和Callable的区别是, (1)Callable规定的方法是call(),Runnable规定的方法是run(). (2)Callable的任务执行后可返回值,而...
  • Qt两种线程创建方式及用途

    千次阅读 2019-05-24 16:12:54
    QThread 使用探讨 2010-10-23 00:30 注意:本文停止更新,请优先考虑 Qt 线程基础(QThread、QtConcurrent等) ...dbzhang800 2011.06.18 ...QThread 似乎是很难的一个东西,特别是信号和槽,非常多...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 833,442
精华内容 333,376
关键字:

创建线程有哪两种方式