关闭

JAVA_线程

4393人阅读 评论(1) 收藏 举报
分类:

一、线程的基本概念

       在操作系统中两个比较容易混淆的概念是进程(process)和线程(thread)。操作系统中的进程是资源的组织单位。进程有一个包含了程序内容和数据的地址空间,以及其它的资源,包括打开的文件、子进程和信号处理器等。不同进程的地址空间是互相隔离的。而线程表示的是程序的执行流程,是CPU调度的基本单位。线程有自己的程序计数器、寄存器、栈和帧等。引入线程的动机在于操作系统中阻塞式I/O的存在。当一个线程所执行的I/O被阻塞的时候,同一进程中的其它线程可以使用CPU来进行计算。这样的话,就提高了应用的执行效率。线程的概念在主流的操作系统和编程语言中都得到了支持。
       一部分的Java程序是单线程的。程序的机器指令按照程序中给定的顺序依次执行。Java语言提供了java.lang.Thread类来为线程提供抽象。有两种方式创建一个新的线程:一种是继承java.lang.Thread类并覆写其中的run()方法,另外一种则是在创建java.lang.Thread类的对象的时候,在构造函数中提供一个实现了java.lang.Runnable接口的类的对象。在得到了java.lang.Thread类的对象之后,通过调用其start()方法就可以启动这个线程的执行。
       一个线程被创建成功并启动之后,可以处在不同的状态中。这个线程可能正在占用CPU时间运行;也可能处在就绪状态,等待被调度执行;还可能阻塞在某个资源或是事件上。多个就绪状态的线程会竞争CPU时间以获得被执行的机会,而CPU则采用某种算法来调度线程的执行。不同线程的运行顺序是不确定的,多线程程序中的逻辑不能依赖于CPU的调度算法。
  Windows操作系统是支持多线程的,它可以同时执行很多个线程,也支持多进程,因此Windows操作系统是支持多线程多进程的操作系统。Linux和Uinux也是支持多线程和多进程的操作系统。DOS就不是支持多线程和多进程了,它只支持单进程,在同一个时间点只能有一个进程在执行,这就叫单线程。
  CPU难道真的很神通广大,能够同时执行那么多程序吗?不是的,CPU的执行是这样的:CPU的速度很快,一秒钟可以算好几亿次,因此CPU把自己的时间分成一个个小时间片,我这个时间片执行你一会,下一个时间片执行他一会,再下一个时间片又执行其他人一会,虽然有几十个线程,但一样可以在很短的时间内把他们通通都执行一遍,但对我们人来说,CPU的执行速度太快了,因此看起来就像是在同时执行一样,但实际上在一个时间点上。
  那什么才是真正的多线程?如果你的机器是双CPU,或者是双核,这确确实实是多线程。

二、线程的创建和启动

  在JAVA里面,JAVA的线程是通过java.lang.Thread类来实现的,每一个Thread对象代表一个新的线程。创建一个新线程出来有两种方法:第一个是从Thread类继承,另一个是实现接口runnable。VM启动时会有一个由主方法(public static void main())所定义的线程,这个线程叫主线程。可以通过创建Thread的实例来创建新的线程。你只要new一个Thread对象,一个新的线程也就出现了。每个线程都是通过某个特定的Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。

Demo1:实现Runnable接口创建和启动新线程
package com.liangdianshui;

public class ThreadRunable {
	public static void main(String args[]) {
		MyRunable mRunable = new MyRunable();
		// r1.run();//这个称为方法调用,方法调用的执行是等run()方法执行完之后才会继续执行main()方法
		new Thread(mRunable).start();  //启动一个线程
		for (int i = 0; i < 10; i++) {
			System.out.println("main:" + i);
		}
	}
}

/**
 * 自定义一个类,实现Runable接口 打印1-10
 *
 */
class MyRunable implements Runnable {
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("MyRunable:" + i);
		}
	}
}
运行结果:

       在我的机子上运行的结果是这样,在你们的机子上运行的结果也可能不一样的!他的运行原理是这样的:


Demo2:继承Thread类,重run()方法创建和启动新的线程
package com.liangdianshui;

public class ThreadExtendThread {
	public static void main(String[] args) {
		MyThread mThread = new MyThread();
		mThread.start(); // 开启一个新的线程
		for (int i = 0; i < 10; i++) {
			System.out.println("main:" + i);
		}
	}
}

/**
 * 继承Thread
 *
 */
class MyThread extends Thread {
	@Override
	public void run() {
		super.run();
		for (int i = 0; i < 10; i++) {
			System.out.println("MyThread: " + i);
		}
	}
}

  使用实现Runnable接口和继承Thread类这两种开辟新线程的方法,在选择上:应该优先选择实现Runnable接口这种方式去开辟一个新的线程。因为接口的实现可以实现多个,而类的继承只能是单继承。因此在开辟新线程时能够使用Runnable接口就尽量不要使用从Thread类继承的方式来开辟新的线程。

       通过上面的例子,我们可以这样理解线程,主线程就是一个部门的主管,当遇到比较耗时的工作的时候,他可以安排部门的其他员工帮忙做,然后他自己继续做下面的事情,最后只要知道员工完成的结果就行了~!

三、线程状态转换
3.1.线程控制的基本方法
3.2. sleep/join/yield方法介绍

Demo

package com.liangdianshui;

import java.util.Date;

public class ThreadRunable {
	public static void main(String args[]) {
		MyRunable mRunable = new MyRunable();
		// r1.run();//这个称为方法调用,方法调用的执行是等run()方法执行完之后才会继续执行main()方法
		new Thread(mRunable).start(); // 启动一个线程
		for (int i = 0; i < 10; i++) {
			System.out.println("main:" + i);
			if (i == 5) {
				try {
					System.out.println(new Date().toLocaleString());  //打印当前时间
					Thread.sleep(5000); // 让主线程休眠5秒
					System.out.println(new Date().toLocaleString());  //打印当前时间
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

/**
 * 自定义一个类,实现Runable接口 打印1-10
 *
 */
class MyRunable implements Runnable {
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("MyRunable:" + i);
		}
	}
}

运行结果:



Demo:

package com.liangdianshui;

import java.util.Date;

public class ThreadRunable {
	public static void main(String args[]) {
		MyRunable mRunable = new MyRunable();
		// r1.run();//这个称为方法调用,方法调用的执行是等run()方法执行完之后才会继续执行main()方法
		Thread mThread = new Thread(mRunable);
		mThread.start(); // 启动一个线程
		for (int i = 0; i < 10; i++) {
			System.out.println("main:" + i);
		}
		try {
			mThread.join();  //把子线程合并到主线程,等于是调用子线程的方法
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

/**
 * 自定义一个类,实现Runable接口 打印1-10
 *
 */
class MyRunable implements Runnable {
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("MyRunable:" + i);
			if (i == 2) {
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
运行结果:

         


          join方法你可以理解为是直接停止了那个子线程,然后在主线程中继续运行!

Demo:
package com.liangdianshui;

import java.util.Date;

public class ThreadRunable {
	public static void main(String args[]) {
		MyThread1 t1 = new MyThread1("t1");
		MyThread1 t2 = new MyThread1("t2");
		t1.start();
		t2.start();
	}
}

class MyThread1 extends Thread {

	private String strName;

	public MyThread1(String str) {
		strName = str;
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(strName + ":" + i);
			try {
				Thread.sleep(1000); //为了更好的显示效果,增加延迟
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (i % 2 == 0) {
				yield();
			}
		}
	}

}
四、线程的优先级别

五、线程同步


六、总结
        这篇博文首先简单的介绍了什么是进程和线程,知道单个CPU不是真正意义上的多进程,CPU把自己的时间分成一个个小时间片,我这个时间片执行你一会,下一个时间片执行他一会,加上CPU的运行速度很快,因此像同时运行多个程序一样,然后了解实现Thread的两种方法,一种是实现Runable接口,一种是继承Thread类,最后讲了线程的一些方法!

0
0
查看评论

Java_线程

多线程 1.简介 在任何时间点,可以有多个程序同时执行,或者有多个程序逻辑同时执行的能力,称为并发执行。 1.1 线程与进程 进程(Process)指操作系统中一个独立运行的程序。进程也称任务,每个进程拥有独立的内存空间等系统资源,进程间的系统不能互用,所以进程间通信较困难。引申出多任务操作系统。c...
  • u011110953
  • u011110953
  • 2013-09-29 22:12
  • 491

Win7 X64配置Java Web开发环境

一、安装JDK         1、这里我用的是jdk-7windows-x64,安装位置为默认C:\Program Files\Java\jdk1.7.0_79         2、安装完成后配置环境变量 ...
  • newtelcom
  • newtelcom
  • 2015-09-04 10:19
  • 769

Java_并发线程_Condition

1.概述 使用Condition应在Lock的前提下,请先参见Java_并发线程_Lock、ReadWriteLock一文。在synchronized同步代码块中使用了obj的锁对象,然后通过obj.notify()和obj.wait()来配合处理多线程的问题。然而,同样lock和condit...
  • strawberry2013
  • strawberry2013
  • 2014-10-29 10:44
  • 1528

java_线程整合

1、线程和进程(linux下fork系统调用以及操作系统详解)   进程:资源分配基本单位   线程:资源占有基本单位 2、单进程:DOS、主线程:main 3、Thread 核心方法run()   **start()  使该线程开始执行...
  • Aaron_xyt
  • Aaron_xyt
  • 2012-03-29 18:11
  • 300

Java_线程-Thread

Java_线程-Thread
  • Ling912439122
  • Ling912439122
  • 2016-09-02 00:35
  • 519

java_基础_线程

一、概述1、一个程序就是一个进程,进程中可以包括多个线程,每一个线程都相当于一个小的进程,并且各个线程之间可以同时运行,这就是java多线程编程。 2、线程的五个状态 ①新建(new) 用new语句创建的线程对处于新建状态,此时它和其它Java对象一样,仅仅在Heap中被分配了内存。当一个线程...
  • a7055117a
  • a7055117a
  • 2015-04-11 19:22
  • 234

Java_线程_ThreadLocal

本博文为子墨原创,转载请注明出处! http://blog.csdn.net/zimo2013/article/details/8952721 public class Test{ private static ThreadLocal localPerson = new ThreadLoc...
  • strawberry2013
  • strawberry2013
  • 2013-05-20 22:12
  • 1132

Java_并发线程_CompletionService

1.CompletionService源码分析 CompletionService内部实现还是维护了一个可阻塞的队列,通过代理设计模式,从而操作队列。 /** * Creates an ExecutorCompletionService using the supplied ...
  • strawberry2013
  • strawberry2013
  • 2014-10-26 15:35
  • 1681

Java_并发线程_Lock、ReadWriteLock

1.Lcok 1 1 11 1
  • strawberry2013
  • strawberry2013
  • 2014-10-29 10:42
  • 2115

Java_基础—多线程(线程安全问题)

多线程并发操作同一数据时, 就有可能出现线程安全问题 使用同步技术可以解决这种问题, 把操作数据的代码进行同步, 不要多个线程一起操作 需求:铁路售票,一共100张票,通过四个窗口卖完 分别使用Thread类和Runnable接口实现
  • SoarFly0807
  • SoarFly0807
  • 2017-09-02 19:30
  • 138
    个人资料
    • 访问:297830次
    • 积分:4229
    • 等级:
    • 排名:第8560名
    • 原创:133篇
    • 转载:7篇
    • 译文:0篇
    • 评论:104条
    个人资料
    博客专栏