多线程
进程:是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。
举例:IDEA, 阿里云盘, wegame, steam
线程:是进程中的单个顺序控制流,是一条执行路径
一个进程如果只有一条执行路径,则称为单线程程序。
一个进程如果有多条执行路径,则称为多线程程序。
思考:
java程序启动时,是单线程程序还是多线程程序?多线程程序的【主线程,垃圾回收线程】
java提供了一个类用来描述线程:Thread
线程是程序中执行的线程。
Java虚拟机允许应用程序同时执行多个执行线程。
每个线程都有优先权, 具有较高优先级的线程优先于优先级较低的线程执行。
实现多线程方式一:继承Thread方法,重写run()方法
点击查看代码
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
@Override
public void run() {
//run方法是将来线程对象启动时要执行的计算逻辑
for(int i=1;i<=200;i++){
System.out.println(getName()+" - "+i);
}
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
//创建一个线程对象
// MyThread t1 = new MyThread();
// MyThread t2 = new MyThread();
MyThread t1 = new MyThread("王骏");
MyThread t2 = new MyThread("张万森");
//给线程起名字
// 方式1:调用setName()方法起名字
// t1.setName("王骏");
// t2.setName("张万森");
// 方式2:使用构造方法起名字
// t1.run();
// t2.run();
t1.start(); // 系统分配资源给线程t1,启动线程,t1线程具备了执行的资格,具体等到抢到cpu执行权的时候才会执行
t2.start();//抢夺cpu
}
}
休眠线程
public static void sleep(long millis)
点击查看代码
class MyThread2 extends Thread{
@Override
public void run() {
System.out.println("我现在开始睡觉了...");
try {//有异常,需要处理异常(try ..catch)
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我醒了,现在开始学习!!");
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
MyThread2 myThread2 = new MyThread2();// new 一个对象
myThread2.start();
}
}
加入线程:
public final void join()
点击查看代码
class MyThread3 extends Thread {
@Override
public void run() {
for (int i = 1; i <= 200; i++) {
System.out.println(getName() + "-" + i);
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread3 t1 = new MyThread3();
MyThread3 t2 = new MyThread3();
MyThread3 t3 = new MyThread3();
t1.start();
t1.join();//具有优先执行的权利
t2.start();
t3.start();
}
}
礼让:
public static void yield()
点击查看代码
class MyThread4 extends Thread{
@Override
public void run() {
for(int i=1;i<=200;i++){
System.out.println(getName()+"- "+i);
Thread.yield();
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
MyThread4 t1 = new MyThread4();
MyThread4 t2 = new MyThread4();
t1.start();
t2.start();
}
}
后台线程:
public final void setDaemon(boolean on)
用户线程:优先级高于守护线程
守护线程【后台线程】:当一个程序没有了用户线程,守护线程也就没有了
点击查看代码
class MyThread5 extends Thread{
@Override
public void run() {
for(int i=1;i<=200;i++){
System.out.println(getName()+"- "+i);
}
}
}
public class ThreadDemo5 {
public static void main(String[] args) {
MyThread5 t1 = new MyThread5();
MyThread5 t2 = new MyThread5();
MyThread5 t3 = new MyThread5();
t1.setName("刘备");
t2.setName("关羽");
t3.setName("张飞");
//将t2和t3线程设置为守护线程
t2.setDaemon(true);
t3.setDaemon(true);
t1.start();
t2.start();
t3.start();
}
}
中断线程:
public final void stop()
public void interrupt()
java所有的线程要想变成运行状态,必须经过抢cpu执行权
点击查看代码
class MyThread6 extends Thread{
@Override
public void run() {
System.out.println("王骏准备睡觉了....睡足10秒钟");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡醒了,继续敲代码!!!");
}
}
public class ThreadDemo6 {
public static void main(String[] args) {
MyThread6 t1 = new MyThread6();
t1.start();
try {
Thread.sleep(5000);
// t1.stop();//在第五秒的时候直接被打死了
t1.interrupt();//在第五秒被打醒了继续学习
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
创建线程的第二种方式:实现Runnable接口,借助Thread类创建线程对象
若将来每一个线程执行的逻辑是一样的话,推荐采用第二种实现Runnable接口方式实现多线程
若将来每一个线程执行逻辑不一样的话,推荐采用第一种继承Thread类方式实现多线程
点击查看代码
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 200; i++) {
//可以先通过获取当前执行的线程对象,调用内部getName()方法
System.out.println(Thread.currentThread().getName()+"-"+i);
}
}
}
public class RunnableDemo1 {
public static void main(String[] args) {
//创建Runnable对象
MyRunnable r1 = new MyRunnable();
//创建线程对象
// Thread t1 = new Thread(r1);
// Thread t2 = new Thread(r1);
// Thread t3 = new Thread(r1);
//创建线程对象同时起名字
Thread t1 = new Thread(r1, "李刚");
Thread t2 = new Thread(r1, "祝帅");
Thread t3 = new Thread(r1, "吴问强");
//获取线程优先权 默认线程优先级是 5
// System.out.println("t1: "+t1.getPriority());
// System.out.println("t2: "+t2.getPriority());
// System.out.println("t3: "+t3.getPriority());
t1.setPriority(1); // 1-10
t1.setPriority(10);
t1.setPriority(1);
t1.start();
t2.start();
t3.start();
}
}
线程组:将属于同一类的线程划分到同一组中,可以直接对线程组进行设置。
ThreadGroup
构造方法:
ThreadGroup(String name) 构造一个新的线程组。
点击查看代码
class MyThread extends Thread{
public MyThread() {
}
public MyThread(ThreadGroup group, String name) {
super(group, name);
}
@Override
public void run() {
System.out.println("美女与野兽");
}
}
public class ThreadGroupDemo1 {
public static void main(String[] args) {
//创建一个线程组,组名叫做帅哥组
ThreadGroup tg1 = new ThreadGroup("美女组");
ThreadGroup tg2 = new ThreadGroup("野兽组");
//分配一个新的 Thread对象。
Thread t1 = new Thread(tg1, "李娜");
Thread t2 = new Thread(tg1, "门金锁");
Thread t3 = new Thread(tg2, "王骏");
Thread t4 = new Thread(tg2, "默默");
//获取组名和组成员
System.out.println(t1.getName()+"在"+t1.getThreadGroup().getName());
System.out.println(t2.getName()+"在"+t2.getThreadGroup().getName());
System.out.println(t3.getName()+"在"+t3.getThreadGroup().getName());
System.out.println(t4.getName()+"在"+t4.getThreadGroup().getName());
//守护线程
t2.setDaemon(true);
}
}
线程池:ThreadPool
Executors:
static ExecutorService newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
static ExecutorService newFixedThreadPool(int nThreads) 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
点击查看代码
class MyRunnable implements Runnable{
private String name;
public MyRunnable() {
}
public MyRunnable(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(getName()+"-"+i);
}
}
}
public class ThreadPoolDemo1 {
public static void main(String[] args) {
//创建一个固定大小的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//Future<?> submit(Runnable task);
pool.submit(new MyRunnable("lina"));
pool.submit(new MyRunnable("wangjun"));
pool.submit(new MyRunnable("wangsan"));
// pool.submit(new MyRunnable());
// <T> Future<T> submit(Callable<T> task);
// pool.submit(new MyCallable());
// pool.submit(new MyCallable());
// pool.submit(new Callable<Object>() {
// @Override
// public Object call() throws Exception {
// for (int i = 1; i <=100 ; i++) {//属于线程池里的接口v实现方法//由于是接口没法调用getName(),
// // 需要通过Thread.ccurrentThread().getName()
// System.out.println(Thread.currentThread().getName()+"-"+i);
//
// }
// return null;
// }
// });
}
}

浙公网安备 33010602011771号