线程指进程中的一个执行场景,也就是执行流程,那么进程和线程的区别是什么
1. 每个进程是一个应用程序,都有独立的内存空间
2. 同一个进程中的线程共享其进程中的内存和资源
(共享的内存是堆内存和方法区内存,栈内存不共享,每个线程有自己的)
什么是进程?
一个进程对应一个应用程序。 例如:在 windows 操作系统启动 Word 就表示启动了一个进程。在 java 的开发环境下启动 JVM,
就表示启动了一个进程。现代的计算机都是支持多进程的,在同一个操作系统中,可以同时启动多个进程。
/*
分析一下程序有几个线程
只有一个线程,就是主线程
main,m1,m2,m3 这四个方法在同一个栈空间中
没有启动其他任何线程
*/
public class ThreadTest01{
public static void main(String[] args){
ming01();
}
public static void arry01(){
ming2();
}
public static void arry02(){
ming03();
}
public static void arry03(){
System.out.println("电子科技大学中山学院");
}
}
/*
在Java语言中实现多线程第一种方式:
1. 继承java.lang.Thread
2. 重写run方法
三个知识点:
定义线程
创建线程
启动线程
*/
public class ThreadTest02{
public static void main(String[] args){
// 创建一个线程
Thread t = new Student();
// 启动线程
t.start();
// start方法执行完瞬间结束,告诉JVM再分配一个新的线程 给t线程
// run 不需要手动调用的,系统线程启动之后会自动调用run方法
// 是随机分配的,没有规律
// t.run(); 这是普通方法的调用,这样做程序只有一个线程,run方法结束之后,下边的程序才能继续运行
for(int i = 0; i < 5; i++){
System.out.println("main---------: "+i);
}
/*
有了多线程之后,main方法结束只是主线程中没有方法栈帧了
但是其他线程或者其他栈中还有栈帧
main方法结束,程序可能还在运行
*/
}
}
class Student extends Thread{
// 重写run方法
public void run(){
for(int i = 0; i < 10; i++){
System.out.println("run: " + i);
}
}
}
/*
Java中实现多线程的第二种方法:
1. 写一个类实现
2. 实现run方法
*/
public class ThreadTest03{
public static void main(String[] args){
// 创建线程
Thread t = new Thread(new Teacher());
// 启动
t.start();
}
}
// 这种方法是推荐的,因为一个类实现接口之外保留了 类的继承
class Teacher implements Runnable {
// 重写run方法
public void run(){
for(int i = 0; i < 10; i++){
System.out.println("run: " + i);
}
}
}
/*
掌握线程方法:
1. 获取当前线程的对象 currentThread
2. 给线程起名 t.setName("名称");
3. 获取线程的名字:t.getName();
*/
public class ThreadTest04{
public static void main(String[] args){
// 获取当前线程对象 main 主线程
Thread t = Thread.currentThread();
// 获取线程的名称
System.out.println("线程的名称:"+t.getName());//输出main
Thread t1 = new Thread(new MingTest());
// 给线程起名
t1.setName("Ming");
t1.start();
Thread t2 = new Thread(new MingTest());
// 给线程重命名
t2.setName("中山学院");
t2.start();
}
}
class MingTest implements Runnable{
public void run(){
Thread t = Thread.currentThread();
System.out.println("线程名称:"+t.getName());
}
}
/*
线程优先级的高的获取cpu的时间片 相对多一些
最高:10
最低:1
默认:5
优先级:1 - 10
优先级高的线程 会得到CPU的时间多一些,优先执行完成
*/
public class ThreadTest05{
public static void main(String[] args){
System.out.println("最高:" + Thread.MAX_PRIORITY);
System.out.println("最小:" + Thread.MIN_PRIORITY);
System.out.println("默认:" + Thread.NORM_PRIORITY);
Thread t1 = new Keke();
t1.setName("t1");
Thread t2 = new Keke();
t2.setName("t2");
// 都是 5
System.out.println("t1优先级:" + t1.getPriority());
System.out.println("t2优先级:" + t2.getPriority());
// 设置优先级
t1.setPriority(6);
t2.setPriority(3);
// 启动
t1.start();
t2.start();
}
}
class Keke extends Thread{
public void run(){
for(int i = 0 ; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----------- : " + i);
}
}
}
/*
Thread.sleep(); 让当前正在执行的线程休眠(暂停执行)
sleep 方法是一个静态方法
该方法的作用:阻塞当前线程,腾出CPU,让给其他线程
*/
public class ThreadTest06{
public static void main(String[] args){
Thread t1 = new Ming();
t1.setName("t1");
t1.start();
// 获取当前线程对象 main 主线程
Thread t = Thread.currentThread();
// 获取线程的名称
System.out.println("线程的名称:"+t.getName());//输出main
// 阻塞主线程
for(int i = 0; i < 20; i++){
System.out.println(Thread.currentThread().getName() + "----------- : " + i);
try{
Thread.sleep(1000);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
class Ming extends Thread{
public void run(){
System.out.println("线程正在启动中.......");
for(int i = 0; i < 20; i++){
System.out.println(Thread.currentThread().getName() + "----------- : " + i);
try{
Thread.sleep(2000); // 让当前程序阻塞2S
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
//输出main跟ti是随机的
/*
Thread.yield(); 暂停当前正在执行的线程对象,并执行其他线程。
1. 该方法是一个静态方法
2. 作用: 给同一个优先级的线程让位,但是让位时间不固定
3. 和sleep方法相同,就是yield时间不固定
他与sleep类似,只是不能由用户指定暂停多长时间,并且yield()只能让 同优先级的线程有执行的机会
*/
public class ThreadTest08{
public static void main(String[] args){
// 创建线程
Thread t = new Ming5();
t.setName("t");
// 启动线程
t.start();
// 主线程
for(int i = 0; i < 20; i++){
System.out.println(Thread.currentThread().getName()+"------- "+i);
}
System.out.println("Ming帅了 !");
}
}
class Ming5 extends Thread{
public void run(){
for(int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName()+"------- "+i);
if(i % 2 == 0){
Thread.yield();
}
}
}
}
/*
线程的合并
*/
public class ThreadTest09{
public static void main(String[] args){
Thread t = new Thread(new Arry6());
t.setName("t");
t.start();
try{
// 合并线程
t.join(); // t 和 主线程合并,单线程的程序
} catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("---------main end--------");
// 主线程
for(int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName()+"------- "+i);
}
// 当前线程可以调用第一个线程的join方法,调用后当前线程会被阻塞不再执行,
// 直到被调用的线程执行完毕,当前线程才会执行
}
}
class Arry6 implements Runnable{
public void run(){
for(int i = 0; i < 10; i++){
try{
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"------- "+i);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}