说道多线程
注意:
这两种实现方式的区别并不大。继承Thread类的方式实现起来较为简单,但是继承它的类就不能再继承别的类了,因此也就不能继承别的类的有用的方法了。而使用是想Runnable接口的方式就不存在这个问题了,而且这种实现方式将线程主体和线程对象本身分离开来,逻辑上也较为清晰,所以推荐大家更多地采用这种方式。
两者这两种启动方法原理是一样的。首先都是调用bending启动一个线程,其次是在线程里执行目标对象的run方法。
当我们采用Runnable接口实现线程时,调用thread(Runnable garget)构造,参数为接口类型的,Runnable,所以线程启动时,实例的run()方法就被执行了。
如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享
![](https://img-blog.csdn.net/20140304155415968?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGFuX3lhbmt1bjIwMDk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
就得来认识下咱们经常说道的几个概念。
进程: 是一个静态的概念,它本身是不能动的,每个进程都是有一个主方法的执行路径,这个路径就是一个具体的线程。
多线程是我们处理多任务的强有力工具。
线程和进程的不同:
- 进程有独立运行的程序,有自己的变量,且不同进程不能共享。
- 线程是运行在进程内部的。不同的线程之间可以在进程范围内共享数据。
- 线程是通过并行处理给用户带来更好的使用体验。
实现进程的两种方式:
- 继承java.lang.Thread,并重写它的run()方法,将线程的执行主体放入其中。
- 实现java.lang.Runnable接口,实现它的run()方法,并将线程的执行主体放入其中。使用runnable接口可以为多个线程提供共享的数据
java代码
继承Thread类实现线程实例
public class TestThread {
public static void main(String args[]) {
TestThread1 r = new TestThread1 ();
r.start();
for(int i=0; i<5; i++) {
System.out.println("Main Thread:------" + i);
}
}
}
class TestThread1 extends Thread {
public void run() {
for(int i=0; i<5; i++) {
System.out.println("Runner1 :" + i);
}
}
}
实现Runnable接口实现多线程实例
public class TestThread {
public static void main(String args[]) {
//实例化接口实现类
Runnable1 r = new Runnable1 ();
//调用构造方法创建线程
Thread t = new Thread(r);
t.start();
for(int i=0; i<5; i++) {
System.out.println("Main Thread:------" + i);
}
}
}
class Runnable1 implements Runnable {
public void run() {
for(int i=0; i<5 i++) {
System.out.println("Runner1 :" + i);
}
}
}
注意:
这两种实现方式的区别并不大。继承Thread类的方式实现起来较为简单,但是继承它的类就不能再继承别的类了,因此也就不能继承别的类的有用的方法了。而使用是想Runnable接口的方式就不存在这个问题了,而且这种实现方式将线程主体和线程对象本身分离开来,逻辑上也较为清晰,所以推荐大家更多地采用这种方式。
如何启动线程:
要启动一个线程,必须调用方法来启动它,这个方法就是Thread类的start()方法,而不是run()方法。
继承Thread调用
public static void main(String args[]) {
TestThread1 r = new TestThread1 ();
r.start();
}
实现Runnable接口的调用
public static void main(String args[]) {
//实例化接口实现类
Runnable1 r = new Runnable1 ();
//调用构造方法创建线程
Thread t = new Thread(r);
t.start();
}
两者这两种启动方法原理是一样的。首先都是调用bending启动一个线程,其次是在线程里执行目标对象的run方法。
当我们采用Runnable接口实现线程时,调用thread(Runnable garget)构造,参数为接口类型的,Runnable,所以线程启动时,实例的run()方法就被执行了。
构造方法摘要
- Thread(Runnable target)
- 分配新的 Thread 对象。
如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。
两者的区别:
public class thread3{
public static void main(String[] args) {
hello h1 = new hello();
hello h2 = new hello();
hello h3 = new hello();
h1.start();//每个线程都各卖了5张,共卖了15张票
h2.start();//但实际只有5张票,每个线程都卖自己的票
h3.start();//没有达到资源共享
}
}
class hello extends Thread {
public void run() {
int count = 5;
for (int i = 0; i < 7; i++) {
if (count > 0) {
System.out.println("count= " + count--);
}
}
}
}
效果图
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享
我们换位Runnable接口
class MyThread implements Runnable{
private int ticket = 5; //5张票
public void run() {
for (int i=0; i<=20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
}
}
}
}
public class lzwCode {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1号窗口").start();
new Thread(my, "2号窗口").start();
new Thread(my, "3号窗口").start();
}
}
效果图
所以
- 1):适合多个相同的程序代码的线程去处理同一个资源
- 2):可以避免java中的单继承的限制
- 3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
以上几点只是线程的基本概念。还没涉及同步,进行状态的装换。初认识java。希望大家多多指点。