好久没有更博客了,最近一直在忙工作的事情。现在终于空下来了,这2天会抓紧时间整理多线程和socket,把JavaSE结束掉。
- 线程和进程
- 什么是进程?
- 什么是线程?
- 关于他们2个之间的关系:
线程是一个操作系统创建并维护的一个资源,对操作系统来说JVM就是一个进程。
对于单个CPU系统来说,某一个时刻只可能由一个线程在运行。一个Thread对象就表示一个线程。
进程是独立的数据空间,线程是共享的数据空间。线程对象存在于虚拟机进程空间的一块连续的地址空间(静态的)。
- 关于线程注意:
2.线程对象与其他对象不同的是线程对象能够到底层去申请管理一个线程资源。
3.只有对线程对象调用start()方法才是到底层去申请管理一个线程资源。
4.任务并发执行是一个宏观概念,微观上是串行的。
5.只有等到所有的线程全部结束之后,进程才退出。进行多线程编程时不要忘记了Java程序运行时默认的主线程,main方法的方法体就是主线程的线程执行体。
- 在这里要注意2个概念上的区别:并行和并发。
并发指的是在同一时刻,只能有一条指令执行。但是多个指令被快速轮换执行,使得在宏观上有多个进程同时执行。也就是说只是看起来是同时执行的,其实具体实际执行的还是一条而已。
- 多线程的优势:
2,系统创建进程需要为进程重新分配系统资源,但创建线程则代价小得多,使用多线程实现多任务并发比多进程的效率高。
3,Java语言内置多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化了Java的多线程编程
- 线程的创建和启动
/**
*
* @version 1L
* @author LinkinPark
* @since 2015-2-3
* @motto 梦似烟花心似水,同学少年不言情
* @desc ^ 继承Thread,重写run方法。
*/
public class MyThread extends Thread
{
private int i = 0;
public void run()
{
for (; i < 10; i++)
{
//输出中i不连续,说明这种方式不能共享一份系统资源
System.out.println(this.getName() + " " + i);
}
}
public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
//输出了主线程
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20)
{
//这里开始抢占输出,注意的是i不连续
new MyThread().start();
new MyThread().start();
}
}
}
}
public class MyThread1 implements Runnable
{
private int i = 0;
@Override
public void run()
{
for (; i < 100; i++)
{
//输出中i连续,表明这种方式会共享同一份系统资源
//这里没有Thread,所以只能通过这种方式:先返回当前正在执行的线程对象,然后在获得名字
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args)
{
for (int i = 0; i < 100; i++)
{
//输出主线程
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20)
{
MyThread1 myThread1 = new MyThread1();
//这里开始抢占输出,注意的是i连续
new Thread(myThread1, "林肯的第一个线程").start();
new Thread(myThread1, "林肯的第二个线程").start();
}
}
}
}
- 关于这2种方式创建线程的对比:
public void run() {
if (target != null) {
target.run();
}
}
这里有一个target,如何理解这个target呢?run方法又叫线程执行体,我们可以这样子来理解,线程呢就是一段程序流,这段程序流要操作一个对象,那么操作的这个对象就是这个target,值得注意的一点是Java语言的Thread必须使用Runnable对象里面的run方法。
言归正传,这2种实现方式的区别如下:
1,实现Runnable接口,还可以继承其他的类。Java是单继承呀,要是直接去继承Thread类的话就不能再继承别的类了
2,实现Runnable接口,多个线程可以共享同一个target对象,所以非常适合多个相同的线程来处理同一份资源
3,实现Runnable接口,编码稍微有点多。访问当前线程只能使用Thread.currentThread(),要是继承Thread类的话直接使用this就可以获得当前的线程。