黑马程序员-多线程

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

 

进程与线程的区别: 

进程有独立的进程空间,进程中的数据存放空间(堆内存和栈内存)都是独立的 

线程的堆内存空间是共享的,栈内存空间才是独立的(堆共享,栈独立)

线程消耗的资源比进程小,相互之间可以影响。

 

多线程的好处:

1.      解决了一个进程里面可以同时运行多个任务(执行路径)。

2.      提供资源的利用率,而不是提高效率。

多线程的弊端:

1.      降低了一个进程里面的线程的执行频率。

2.      对线程进行管理要求额外的 CPU开销。线程的使用会给系统带来上下文切换的额外负担。

3.      公有变量的同时读或写。当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,发生线程安全问题。

4.      线程的死锁。即较长时间的等待或资源竞争以及死锁等多线程症状。

 

创建线程方式一

继承Thread类(extends

1.

子类覆盖父类中的run方法,将线程运行的代码存放在run中。

2.

建立子类对象的同时线程也被创建。

3.

通过调用start方法开启线程。

创建线程方式二(一般是使用这个)

实现Runnable接口(implements)

1.

子类覆盖接口中的run方法。

2.

通过Thread类创建线程,并将实现了Runnable接口的子类对象作为参数传递给Thread类的构造函数。

3.

Thread类对象调用start方法开启线程。

PS:多线程提高了CPU的利用率,不是提高CPU的效率,效率是固定的

思考:为什么要给Thread类的构造函数传递Runnable的子类对象?

因为自定义的run方法所属的对象是Runnable接口的子类对象

要让Thread线程去执行传入对象的run方法

我的理解:Thread类的构造函数传递Runnable的子类对象,其实就是Thread类的构造函数接受一个子类对象的引用,可以想象在Thread类的内部实现应该是如下这样

public class Thread_1 extends Object {
	Runnable target = null;// 声明一个Runnable引用;

	Thread_1()// 空参数构造函数
	{
	}

	Thread_1(Runnable target) {
		this.target = target;
	}

	void run() {
		if (target != null) // 如果传入了对象,就调用传入对象的run()
		{
			target.run();
		}
	}
}

 

其实这样更好理解继承Thread类和实现Runnable开辟线程的不同之处

如果是继承Thread,则要重写run方法,实现自己定义的线程方法

如果是实现Runnable,Thread构造函数中传入子类对象呢?则如上代码,虽说没有覆盖,但是ThreadRun方法里面还是通过传入的子类对象调用自定义run方法

其实归根结底,还是Thread创建的线程

 

实现接口方式和继承方式有什么区别呢?

java中是不允许类实现多继承的,但是如果一个A类中有一部分代码需要多线程执行,采用第一种方法实现的话,就继承了Thread类,不能再继续继承其他类,限制了A类功能的扩展

java已经考虑到这种情况,采用第二种实现多线程的方法的话,既可以在继承其他功能类的同时,可以通过实现接口的方法实现多线程

以上就是两者区别

 

实现方式好处:避免了单继承的局限性。

在定义线程时,推荐使用实现接口方式。

 

中断线程:

Interrupt()可以中断某一线程的运行状态

守护线程(后台线程):

Demo d1 = newDemo();

Thread d1 = new Thread(t);

d1.setDaemon(true);//设置为守护线程

d1.start();

当前台有一个线程在运行,整个java进程都不会消失,如果把线程设置为守护线程,并且运行,那么如果在该线程运行的当中,main()方法主线程结束了,那么守护线程就会立刻结束,守护线程的非守护线程的区别是在于,非守护线程的结束条件和主线程不存在关系,即使主线程结束了,run()里的循环代码是while(true),那么线程会一直执行而不会结束,但是守护线程的结束条件除了和自身设置的循环条件外,还和前台线程绑定在了一起,如果前台结束了,那么该守护线程也立刻结束,无论线程内部的循环条件是否满足

{

       System.out.println(1);

       System.out.println(2);

       System.out.println(3);

       System.out.println(4);

}

 

守护线程就跟着结束

垃圾回收器线程就是一个典型的守护线程

 

Join让步线程(也可理解为让某线程强制运行)

使用join方法能够让一个线程强制运行,强制运行期间,其他线程无法运行,必须等次线程完成之后才可以继续运行

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值