1.基础操作

一.并行和并发(微观概念)

  1. 并行:指两个或多个事件在同一个时刻发生
  2. 并发:指两个或多个事件在同一个时间段内发生

image

二.进程和线程

  1. 进程是指一个内存中运行中的应用程序,每个进程都有自己独立的一块内存空间.一个程序可以启动多个进程.

  2. 线程是指进程中的一个执行任务(控制单元),一个进程可以同时并发运行多个线程.

  3. 多任务系统,该系统可以运行多个进程,一个进程也可以执行多个任务,一个进程可以包含多个线程.

  4. 一个进程至少有一个线程,为了提高效率,也可以在一个进程中开启多个执行任务,即多线程.

  5. 多进程:操作系统中同时运行的多个程序.

  6. 多线程:在同一个进程中同时运行多个程序.

  7. 进程和线程的区别:

    1. 进程:有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线程.
    2. 线程:堆空间是共享的,栈空间是独立的,线程消耗的资源也比进程小,相互之间可以影响,又称
      为轻型进程或进程元
      因为一个进程中的多个线程是并发运行的,那么从微观角度上考虑也是有先后顺序的,那么哪个线程执行
      完全取决于CPU调度器(JVM来调度),程序员是控制不了的.
    3. 我们可以把多线程并发看做是多个线程在瞬间抢CPU资源,谁抢到资源谁就运行,
      Java程序的进程里至少包含主线程和垃圾回收线程(后台线程).

三.多线程优势

  1. 进程之前不能共享内存,而线程之间共享内存(堆内存)则很简单
  2. 系统创建进程时需要为该进程重新分配系统资源,创建线程则代价小很多,因此实现多任务并发时,
    多线程效率更高,
  3. Java语言本身内置多线程功能的支持,而不是单纯的作为底层系统的调度方式,从而化简了多线程编程

四.创建进程操作

新建ProcessDemo.java

public class ProcessDemo {
	public static void main(String[] args) throws Exception {
		//方式一:打开记事本,Runtime的exec()
		Runtime r = Runtime.getRuntime();
		r.exec("notepad");
		
		//方式二:ProcessBuilder的start
		ProcessBuilder pb = new ProcessBuilder("notepad");
		pb.start();
	}
}

五.使用继承方式创建并启动线程

  1. 方式1:继承Thread类
  2. 方式2:实现Runable接口
  3. 线程类(java.lang.Thread):Thread类和Thread的子类才能称之为线程类,阅读API
  4. 主线程(main方法运行,表示主线程).

  1. 方式1:继承Thread类:
    步骤:

    1. 定义一个类:A继承java.lang.Thread类
    2. 在A类中覆盖Thread类中的run方法
    3. 我们在run方法中编写需要执行的操作----->run方法里的,线程执行体
    4. 在main方法(线程)中,创建线程对象,并启动线程.
    创建线程类:			 	A类 a = new A类();
    调用线程对象的start方法 :	a.start();//启动一个线程
    

注意:千万不要调用run方法,如果调用run方法好比是对象调用方法,依然还是只有一个线程,并没开启新的线程.线程只能调用一次.

新建TreadCreatDemo.java

class MusicThread extends Thread{
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("播放音乐");
		}
	}
}
public class TreadCreatDemo {
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			System.out.println("打游戏");
			if (i == 10) {
				MusicThread mt = new MusicThread();
				mt.start();
			}
		}
	}
}

六.实现Runnable接口

  1. 定义一个类A实现java.lang.Runnable接口,注意A类不是线程类
  2. 在A类中覆盖Runnable接口中的run方法
  3. 我们在run方法中编写需要执行的操作,----->run方法里的线程执行体
  4. 在main方法(线程)中,创建线程对象,并启动线程.
创建线程类对象:			    Thread t = new Tread(new A);
调用线程对象的start方法:	t.start();

新建ImplementsRunnable.java

class MusicRunnable implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("播放音乐");
		}	
	}
}
public class ImplemensRunnableDemo {
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			System.out.println("打游戏");
			if (i == 10) {
				Thread t = new Thread(new MusicRunnable());
				t.start();
			}
		}
	}
}

七.使用匿名内部类创建并启动线程

image

新建AnonymousInnerClassDemo.java

public class AnonymousInnerClassDemo {
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			System.out.println("打游戏");
			if (i == 10) {
				//test1();
				test2();
			}
		}
	}
	
	private static void test2() {
		new Thread() {
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.out.println("播放音乐");
				}
			}
		}.start();
	}

	public static void test1() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.out.println("播放音乐");
				}
			}					
		}).start();
	}
}

八.吃苹果比赛

image

继承方式
会导致一些问题,使用堆字段的话,每个人都吃同一个编号的苹果,

新建ExtendsDemo.java

class Person extends Thread{
	public int apple = 50;
	public Person(String name) {
		super(name);
	}
	public void run() {
		for (int i = 0; i < 50; i++) {
			System.out.println(this.getName() + "吃了编号为 : " + apple-- + "的苹果");
		}
	}
}
public class ExtendsDemo {

	public static void main(String[] args) {
		new Person("小A").start();
		new Person("小B").start();
		new Person("小C").start();
	}
}

实现接口
新建ImplementDemo.java

class Apple implements Runnable{
	private int applenum = 50;
	@Override
	public void run() {
		for (int i = 1; i < 51; i++) {
			if(applenum > 0)
			System.out.println(Thread.currentThread().getName() + 
" 吃了编号为 : " + applenum-- + "的苹果");
		}	
	} 
}

public class ImplementsDemo {
	public static void main(String[] args) {
		Apple a = new Apple();
		new Thread(a,"小A").start();
		new Thread(a,"小B").start();
		new Thread(a,"小C").start();
	}
}

九.继承方式和实现接口的区别

  1. 继承方式:
    1. Java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了
    2. 从操作上分析,继承方式更简单,获取线程名字也简单
    3. 从多行程共享同一个资源上分析,继承方式不能做到
  2. 实现方式
    1. Java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口(设计上更优秀)
    2. 从操作上分析,实现方式,稍微复杂点,获取线程名字也比较复杂,得使用Thread.currentThread()来获取
      当前对象的引用
    3. 从多线程共享一个资源上分析,实现方式可以做到.(是否共享同一个资源)
发布了58 篇原创文章 · 获赞 0 · 访问量 710

猜你喜欢

转载自blog.csdn.net/huang_kuh/article/details/105250737