java学习(22)线程(1)

 * 一、进程
 *    进程指运行中的应用程序,每个进程都有自己独立的地址空间(内存空间)如用户点击桌面的IE浏览器,就启动了一个进程。
 *    操作系统就会为该进程分配独立的地址空间。当用户再次点击左面的IE浏览器,就又启动了一个进程。操作系统将为新进程分配新的独立的地址空间。
 *    目前操作系统都支持多进程。(尝试去使用别人的地址空间,被认为是病毒。一般正常软件只会在自己的地址空间运行。)
 * 二、线程
 *    线程是进程中的一个实体,是被系统独立调动和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,
 *    但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。
 *    线程有就绪,阻塞和运行三种基本状态。
 *    1.什么是线程?
 *      (1)线程是轻量级的进程。
 *      (2)线程没有独立的地址空间(内存空间)
 *      (3)线程是由进程创建的(寄生在进程中)(例:迅雷进程创建每一个下载的文件,每个文件就是一个线程)
 *      (4)一个进程可以拥有多个线程。即多线程编程
 *      (5)线程有五种状态
 *         a.新建状态(new)
 *         b.就绪状态(Runnable)
 *         c.运行状态(Running)
 *         d.阻塞状态(Blocked)
 *         e.死亡状态(Dead)
 *         线程刚被创建,会立马进行一个可运行状态,即就绪状态,然后才会进入运行状态。当出现内存不够用,或文件被别人打开等情况,
 *         会出现阻塞状态。当发现资源可用时,会进入就绪状态,判断内存等没有问题后,进入运行状态。运行到一定情况下,进入死亡状态。
 *    2.线程的用处(“不会使用线程就别说自己学过JAVA”)
 *      高并发会用到多线程。只要应用程序涉及到并发,就离不开多线程编程。
 *    3.如何使用?
 *      在Java中一个类要当做线程来使用有两种方法。
 *      (1)继承THread类,并重写run函数。
 *      (2)实现Runnable接口,并重写run函数。(由于java是单继承,在某些情况下,一个类可能已经继承了某个父类,所以需要通过调用接口来实现)
 *    
 *    4.Thread 和 Runnable 的区别
 *      Thread 和 Runnable 本质上没有任何区别。需要注意点如下:
 *      (1)尽可能多使用 Runnable 接口来创建线程。
 *      (2)在使用Thread的时候只需要new一个出来,调用start方法即可。

 *      (3)在使用Runnable的时候,需要先new一个实现Runnable的实例,之后用Thread调用。

package com.shuiyixin1;

public class learnJ_013xiancheng {

	/**
	 * @作者:shuiyixin
	 * @日期:2018.02.26
	 * @内容:线程
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		//1.创建一个Cat013对象
		//如果采用Cat013 cat013 = new Cat013();会报错:
		//No enclosing instance of type learnJ_013xiancheng is accessible. Must qualify the allocation with an enclosing instance of type learnJ_013xiancheng (e.g. x.new A() where x is an instance of learnJ_013xiancheng).
		//意思是:没有任何类型 TestThread 的外层实例可访问。必须用类型 TestThread 的外层实例(例如,x.new A(),其中 x 是 TestThread 的实例)来限定分配。
		//解决方法1:将外部类实现对象,并调用方法。
		learnJ_013xiancheng obj = new learnJ_013xiancheng();
		Cat013 cat013 = obj.new Cat013();
		cat013.start();
		//解决方法2:将内部类设置为静态类,因为类中的静态方法不能直接调用动态方法。
		//只有将某个内部类修饰为静态类,然后才能够在静态类中调用该类的成员变量与成员方法。
		Dog013 dog013 = new Dog013();
		
		Fish013 fish = obj.new Fish013();
		//创建一个Thread
		Thread t = new Thread(fish);
		t.start();
		
		/**
		 * 由于双方都使用了sleep,代码输出如下:
		 * hello world!1
		 * hello fish!1
		 * hello world!2
		 * hello fish!2
		 * hello world!3
		 * hello fish!3
		 * 如果有一方没有使用sleep,即没有阻塞状态,只要运行到,就会全部优先输出。
		 * 是否是交替执行,取决于sleep的数值。
		 * 注意,线程一旦定好,程序员无法控制。
		 */
	}

	class Cat013 extends Thread{
		int times = 0;
		public void run(){
			while (times<3) {
				try {
					//sleep会让线程进入到Blocked状态并释放资源。
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("hello world!" + (times+1));
				times++;
				
			}
		}
	}
	
	public static class Dog013 extends Thread{
		public void run(){
			//System.out.println("hello world!");
		}
	}
	public class Fish013 implements Runnable{

		int times = 0;
		public void run() {
			while (times<3) {
				try {
					//sleep会让线程进入到Blocked状态并释放资源。
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("hello fish!" + (times+1));
				times++;
			}
		}
	 }
	public class Bird013 implements Runnable{
		int n = 0;
		int res = 0;
		int times = 0;
		
		public void run() {
			while (times == n ) {
				try {
					//sleep会让线程进入到Blocked状态并释放资源。
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				res += ++times;
			}
			System.out.println("当前结果是:" + res);
		}
		public int getN() {
			return n;
		}
		public void setN(int n) {
			this.n = n;
		}
		public int getRes() {
			return res;
		}
		public void setRes(int res) {
			this.res = res;
		}
		public int getTimes() {
			return times;
		}
		public void setTimes(int times) {
			this.times = times;
		}
		
	}
}

猜你喜欢

转载自blog.csdn.net/shuiyixin/article/details/79382926