多线程的理解

什么是多线程:

多线程顾名思义就是有多个线程在执行任务,就像小龙女左手画圆,右手画正方形一样。它实在

CPU的调度下来回切换的,但是因为人的视觉感官的问题,觉得在同时执行的。

多线程的意义:

可以充分利用CPU资源,在一个线程被执行的时候,多余出来的CPU资源,可以分配给其他的线

程来执行。

程序 进程 线程:

程序:是一个静态概念,电脑上未曾运行时的应用都算,比如qq,浏览器等;学术化一些的说法

有,可以执行的静态文件;其实我们可以看到安装的程序都是由一堆文件组成;

进程:系统分配资源的最小单位;程序的一次动态执行过程;一个程序可以有多个进程,一个进程

必定只属于一个程序;进程可以被系统划分好独立的地址;进程之间的内存空间互不干扰;

线程:线程是最小的执行单元,同一个进程有多个线程,同一个进程内的线程共享同个内存空间,

而且有的线程之间相互依赖;

实现线程的方法:

 继承Thread类,重写Run方法

public class thread extends Thread {
	@Override
	public void run() {
		
		for (char i = 'A'; i <'z'; i++) {
			String threadName = currentThread().getName();
			System.out.println("thread:"+i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	
	}

}

实现Runable接口,重写Run方法

public class rubthread  implements Runnable{
	@Override
	public void run() {
		
		for (int i = 0; i <= 10000; i++) {
			String threadName = thread.currentThread().getName();
			System.out.println(threadName+":"+i);
		}
	}
}

实现Callable接口,实现call方法

public class callThread implements Callable<String> {
	String str = new String();

	@Override
	public String call() throws Exception {

		for (int i = 0; i <= 10000; i++) {
			String threadName = thread.currentThread().getName();
			System.out.println(threadName + ":" + i);
			str = str + i;
		}

		return str;
	}

}

值得注意的是,与Runable相比,callable多了返回值

通过Exexutor的工具创建线程池,通过线程池获取线程:

public class Pool {
	public static void main(String[] args) {
		// 创建=线程池
		ExecutorService pool = Executors.newFixedThreadPool(10);
		// 提交一个逻辑处理对象,线程池分配一个空闲线程
		pool.execute(new rubthread());
		pool.execute(new rubthread());

		while (true) {
			pool.execute(new Runnable() {

				@Override
				public void run() {
					System.out.println("创建线程:" + Thread.currentThread().getName());
					try {
						thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}

这些就是线程的创建方法

因为线程是由JVM调度的,我们没法准确控制谁先谁后,但是在Thread中的可以影响线程的执行

Sleep方法:

使线程按我们指定的时间来进行休眠

public class Pool {
	public static void main(String[] args) {
		// 创建=线程池
		ExecutorService pool = Executors.newFixedThreadPool(10);
		// 提交一个逻辑处理对象,线程池分配一个空闲线程
		pool.execute(new rubthread());
		pool.execute(new rubthread());

		while (true) {
			pool.execute(new Runnable() {

				@Override
				public void run() {
					System.out.println("创建线程:" + Thread.currentThread().getName());
					try {
						// 休眠3000毫秒
						thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}
}

setPriority方法: 

使用setPriority 方法对线程的优先级进行设置  范围为(1-10),默认为 5 

public class Main {
    public static void main(String[] args) {
       // 创建子线程:打印数字1-26
       Thread thread1 = new Thread("数字线程") {
            @Override
            public void run() {
                for (int i = 1; i <= 26; i++) {
                    System.out.println(Thread.currentThread().getName() + "打印=>" + i + "[" + Thread.currentThread().getPriority() + "]");
                }
            }
        };

        // 创建子线程:打印字母A-Z
        Thread thread2 = new Thread("字母线程") {
            @Override
            public void run() {
                for (char i = 'A'; i <= 'Z'; i++) {
                    System.out.println(Thread.currentThread().getName() + "打印=>" + i + "[" + Thread.currentThread().getPriority() + "]");
                }
            }
        };

        thread1.setPriority(8); // 设置数字线程优先级=8
        thread2.setPriority(1); // 设置字母线程优先级=1

        // 启动子线程
        thread1.start();
        thread2.start();
    }
}

Join方法:

join方法实现插队操作,

public class thread01 {
	public static void main(String[] args) throws InterruptedException {
		
		Thread t1 = new Thread( new Runnable() {
			
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.out.println("T1:"+i);
				}
				
			}
		}) ;
		
		
		Thread t2= new Thread(new Runnable() {
			
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
				System.out.println("T2:"+i);	
				}
				
			}
		});
		// 启动线程
		t1.start();
		t2.start();
		
		// 插队到主线程前
		t1.join();
		t2.join();	
	}

}

interrupt( )方法:

中断线程,当一个线程要执行一个长时间任务的时候,就可能使用interruput来中断线程。

public class Demo {
	public static void main(String[] args) {
		System.out.println("主线程开始");
		// 创建子线程
		Thread thread = new Thread() {
			public void run() {
				System.out.println("子线程开始执行,进入RUNNABLE状态");
				try {
					// 子线程休眠6秒,进入TIMED_WAIT计时等待状态
					Thread.sleep(1000 * 6);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("子线程结束执行,进入TERMINATED状态");
			}
		};

		// 启动子线程
		thread.start();

		// main主线程休眠5秒
		try {
			Thread.sleep(1000 * 3);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// main主线程修改子线程的中断状态=true
		// 子线程检测中断状态=true,则抛出InterruptedException,子线程执行结束
		thread.interrupt();
		System.out.println("主线程结束!");
	}
}

yield( )方法

线程会调用Yieid方法来告诉JVM愿意让出CPU给其他线程,当时采不采用就取决于,当前JVM调度模型 :分时调度,抢占调度

public class Demo4 {
	public static void main(String[] args) {
		System.out.println("主线程启动!");
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				for (int i = 0; i < 50; i++) {
					System.out.println(i);
				}
			}
		};
		
		
		Thread t2 = new Thread() {
				@Override
				public void run() {
				
					for (char i = 'A'; i <'z'; i++) {
						System.out.println("让个他");
						// 调用yeild方法让出本次CPU资源
						Thread.yield();
						System.out.println(i);
					}
				}
		};
		t1.start();
		t2.start();
	}
}

同时日常使用中,除了有我们可以感知的用户线程外,还有线程的守护者,这就是守护线程

守护线程如同骑士一般,默默守护着用户线程

setDaemon:

设置守护线程

public class Demo5 {
	public static void main(String[] args) throws InterruptedException {
		Thread t1 = new Thread() {
			@Override
			public void run() {
				while(true) {
					System.out.println("login-------");
				}
			}
		};
		// 设置守护线程
		t1.setDaemon(true);
		t1.start();
		
		
		Thread t2  = new  Thread() {
			@Override
			public void run() {
				while (!isInterrupted()) {
					System.out.println("User-----------");
				}
				
				System.out.println("User结束!-------------------------");
			}
			
		};
		t2.start();	
		Thread.sleep(10);
		t2.interrupt();
		System.out.println("主线程结束!");
	}
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程的意义在于提高程序的并发性和响应性。通过使用多线程,可以同时执行多个任务,从而提高程序的运行效率和性能。 具体来说,Java多线程的意义包括以下几个方面: 1. 提高程序的并发性:多线程可以使程序同时执行多个任务,充分利用计算机的多核处理器和资源,提高程序的并发性。通过将任务分解为多个线程并行执行,可以加快程序的运行速度。 2. 提高程序的响应性:在单线程程序中,如果某个任务需要花费较长时间才能完成,那么整个程序都会被阻塞,无法响应其他任务。而使用多线程可以将耗时的任务放在一个线程中执行,其他线程可以继续执行其他任务,从而提高程序的响应性。 3. 改善用户体验:在图形界面应用程序中,使用多线程可以使界面保持响应,不会因为某个任务的阻塞而导致界面卡顿或无响应。例如,在下载文件时,可以将下载任务放在一个线程中执行,同时界面仍然可以响应用户的操作。 4. 实现复杂的并发控制:多线程可以实现复杂的并发控制逻辑,例如生产者-消费者模型、读写锁、线程池等。通过合理地使用多线程,可以实现高效的资源共享和协作。 5. 提高系统的可扩展性:使用多线程可以将任务分解为多个独立的子任务,每个子任务由一个线程负责执行。这样,当需要增加处理能力时,只需增加线程的数量,而不需要修改整个程序的结构。 总之,Java多线程的意义在于提高程序的并发性和响应性,改善用户体验,实现复杂的并发控制,以及提高系统的可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值