进程和线程

  • 进程:指的是正在运行的一个应用程序,是系统分配资源的独立单位,每一个进程都有它自己的内存空间和系统资源
  • 线程:在一个进程内又可以执行多个任务,每个任务都可以看做是一个线程。线程是CPU调度的最小单位,线程没有自己的内存空间和资源。
  • 线程的执行是有随机性的,我们无法确定在某一时刻执行的是哪个线程。
  • jvm的启动是多线程的,至少包括主线程和垃圾回收线程(防止内存溢出)两个线程

多线程的实现方式:

继承Thread类,重写run方法,run()方法里面包含的是需要被线程执行的代码。

1.创建线程类:

public class MyThread extends Thread {

	@Override
	public void run() {
		for(int i=0;i<10;i++)
			System.out.print(i+" ");
	}
}

2.创建多个线程,启动线程

public class MyThreadDemo {

	public static void main(String[] args) {
		MyThread m=new MyThread();
		MyThread m2= new MyThread();
		m.start();
		m2.start();
	}

}

3.执行结果:

//第一次:
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 
//第二次:
0 0 1 2 3 1 2 4 3 4 5 5 6 7 8 9 6 7 8 9 
//第三次:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

注意:

  • 在启动线程的时候并不是直接调用run方法,而是调用start方法来启动线程,直接调用run 方法表示普通方法的调用,并不能体现多线程的效果,调用start方法是先启动线程,然后由jvm调用线程的run方法。
  • 构造方法里面也可以传入参数,设置线程名,但是需要在子类中写构造方法。默认的线程名是:Thread-编号
public class MyThread extends Thread {

	public MyThread() {
		
	}
	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		for(int i=0;i<10;i++)
			System.out.print(i+" ");
	}
}
public class MyThreadDemo {

	public static void main(String[] args) {
		
		//默认线程名
		MyThread m=new MyThread();
		MyThread m2= new MyThread();
		//m.start();
		//m2.start();
		//带参构造方法设置线程名
		MyThread m3=new MyThread("线程3");
		
		//seetName方法设置线程名
		MyThread m4=new MyThread();
		m4.setName("线程4");
		
		
		System.out.println(m.getName());
		System.out.println(m2.getName());
		System.out.println(m3.getName());
		System.out.println(m4.getName());
	}

}

执行结果:

Thread-0
Thread-1
线程3
线程4
  • 也可以使用Thread.currentThread().getName()方法获取线程名
    public static Thread currentThread()是静态方法,返回当前正在执行的线程对象的引用
实现Runnable接口,实现run方法
public class MyRunnable implements Runnable {

	//创建MyRunnable实现Runnable接口,实现run方法
	@Override
	public void run() {
		for(int i=0;i<10;i++)
			System.out.print(i+" ");

	}

}
public class MyRunnableDemo {

	public static void main(String[] args) {
		
		MyRunnable my=new MyRunnable();//创建MyRunnable对象
		
		//创建两个线程并将my对象作为参数
		Thread t1=new Thread(my);
		Thread t2=new Thread(my);
		//启动两个线程
		t1.start();
		t2.start();
	}

}

运行结果:

//第一次
0 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 
//第二次
0 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 
//第三次
0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 5 6 7 8 9 
//第四次
0 0 1 2 3 4 1 2 3 4 5 6 7 8 9 5 6 7 8 9

为什么有了方式一还要提供方式二:

  • 因为方式一是继承Thread类,若一个类已经继承了某个类,此时它就不能继承Thread类了,方式二可以避免单继承的局限性。通常以方式二为主。

(个人学习总结,仅供参考)