java多线程的入门研究

it2025-10-16  9

java多线程的入门研究

一.多线程的核心概念二.线程状态线程状态:a.停止线程(stop)b.线程休眠(sleep)c.线程礼让(yield)d.线程插队(Join)e.线程的优先级f.守护(daemon)线程 三.多线程的三种创建方式四.多线程其他扩展a.多线程之Lambda表达式b.多线程之ReentrantLockc.多线程之JUCd.管程法e.使用Runnable创建线程池

一.多线程的核心概念

1.线程就是独立的执行路径; 2.在程序运行时,即使没有自己创建的线程,后台也会有多个线程,如主线程、gc线程 3.main()称之为主线程,为系统的入口,用于执行整个程序; 4.在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密关联的,先后顺序是不能人为的关于; 5.对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制; 6.线程会带来额外的开销,如cpu调度时间,并发控制时间; 7.每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

二.线程状态

线程状态:

NEW:尚未启动的线程处于此状态。RUNNABLE:在java虚拟机中执行的线程处于此状态。BLOCKED:被阻塞等待监视器锁定的线程处于此状态。WAITTING:正在等待另一线程执行特定的动作线程处于此状态。TIMED_WAITTING:正在等待另一线程执行动作达到指定等待时间的线程处于此状态。TERMINATED:已退出的线程处于此状态。

线程方法:

方法说明setPriority(int newPriority)更改线程的优先级static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠void join等待该线程终止static void yield()暂停当前正在执行的线程对象,并执行其他线程(礼让)void interrupt()中断线程,别用这个方式boolean isAlive()测试线程是否处于活动状态

线程通信

方法名作用wait()表示线程一直等待,直到其他线程通知,与sleep不通,会释放锁wait(long timeout)指定等待的毫秒数notify()唤醒一个处于等待状态的线程notifyAll()唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度

a.停止线程(stop)

不推荐使用JDK提供的stop()、destroy()方法 。【已废弃 】推荐线程自己停下来。建议使用一个标志位进行终止变量,当flag=false,则终止线程运行。

示例:线程停止代码示例

public class ThreadStop implements Runnable{ private static boolean flag = true; public void run() { while(flag) { System.out.println("我在疯狂的循环中---"); } } public static void main(String[] args) { new Thread(new ThreadStop()).start(); for(int i = 0;i < 1000;i++) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if (i == 50) { flag = false; } } } }

b.线程休眠(sleep)

sleep(时间)指定当前线程阻塞的毫秒数;sleep存在异常InterruptedException;sleep时间达到后线程进入就绪状态;sleep可以模拟网络延时,倒计时等;每一个对象都有一个锁,sleep不会释放锁;

c.线程礼让(yield)

礼让线程,让当前正在执行的线程暂停,但不阻塞;让线程从运行状态转为就绪状态;让cpu重新调度,礼让不一定成功!看cpu心情;

d.线程插队(Join)

Join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞可以想象成插队 public class ThreadJoin implements Runnable{ public static void main(String[] args) { Thread t = new Thread(new ThreadJoin()); t.start(); for (int i = 0; i < 500; i++) { if (i == 20) { try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("普通客户:"+i); } } public void run() { for (int i = 0; i < 100; i++) { System.out.println("线程VIP:"+i); } } }

e.线程的优先级

java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行。线程的优先级用数字表示,范围从1~10 Thread.MIN_PRIORITY = 1;Thread.MAX_PRIORITY = 10;Thread.NORM_PRIORITY = 5; 使用以下方式改变或获取优先级 getPriority()setPriority(int xxx)

f.守护(daemon)线程

线程分为用户线程和守护线程(mian()线程代表用户线程,gc()代表守护线程)虚拟机必须确保用户线程执行完毕虚拟机不用等待守护线程执行完毕如:后台记录操作日志,监控内存,垃圾回收等待… public class ThreadDaemon{ public static void main(String[] args) { // 打开守护线程 God god = new God(); Thread t = new Thread(god); t.setDaemon(true);// true:代表开始守护线程,false:默认,代表用户线程 t.start(); new Thread(new People()).start(); } } class God implements Runnable{ public void run() { while(true) { System.out.println("---上帝在保护着你----"); } } } class People implements Runnable { @Override public void run() { for(int i = 0;i < 50;i++) { System.out.println("----人民在快乐的生活着---"); } } }

三.多线程的三种创建方式

extends Thread类;implements Runnable接口;implements Callable接口;

例1:extends Thread类;

public class Thread1 extends Thread{ private String name; public Thread1 (String name) { this.name = name; } public void run() { while(true) { System.out.println("我是一个兔子---"); } } public static void main(String[] args) { new Thread1("张三").start(); } }

例2: implements Runnable接口;

public class Thread2 implements Runnable{ private String name; public Thread2 (String name) { this.name = name; } public Thread2() { } public void run() { while(true) { name = Thread.currentThread().getName(); if(name.equals("张三")) { for(int i = 0;i < 100;i++) { System.out.println("---我是张三-"+i); } break; } if(name.equals("李四")) { for(int i = 0;i < 100;i++) { System.out.println("---我是李四-"+i); } break; } } } public static void main(String[] args) { Thread2 t = new Thread2(); new Thread(t,"张三").start(); new Thread(t,"李四").start(); } }

例3:implements Callable接口

public class Thread3 implements Callable<Boolean>{ private String name; public Thread3 (String name) { this.name = name; } public Thread3() { } public Boolean call() { System.out.println("--"+name); return true; } public static void main(String[] args) throws InterruptedException, ExecutionException { Thread3 t1 = new Thread3("张三"); Thread3 t2 = new Thread3("李四"); Thread3 t3 = new Thread3("王五"); // 1.创建执行服务 ExecutorService ex = Executors.newFixedThreadPool(3); // 2.提交执行 Future<Boolean> r1 = ex.submit(t1); Future<Boolean> r2 = ex.submit(t2); Future<Boolean> r3 = ex.submit(t3); // 获取结果 boolean rs1 = r1.get(); boolean rs2 = r2.get(); boolean rs3 = r3.get(); // 关闭服务 ex.shutdownNow(); } }

四.多线程其他扩展

a.多线程之Lambda表达式

Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)

代码示例:

for (int i = 0;i < 10000;i++) { new Thread( // lambda表达式 ()->{ list.add(Thread.currentThread().getName()); } ).start(); } }

b.多线程之ReentrantLock

public class ThreadLock implements Runnable{ public static void main(String[] args) { ThreadLock t2 = new ThreadLock(); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); new Thread(t2).start(); } private int ticketNums = 10; final transient ReentrantLock lock = new ReentrantLock(); @Override public void run() { while(true) { try { lock.lock(); if (ticketNums <= 0) { break; } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(ticketNums--); } finally { lock.unlock(); } } } }

c.多线程之JUC

1.CopyOnWriteArrayList

public class ThreadJucList { public static void main(String[] args) { // 理论上线程安全,实际存在删除操作的时候会存在数组越界的风险,固不是绝对的安全 CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>(); for (int i = 0;i < 10000;i++) { new Thread( // lamda表达式 ()->{ list.add(Thread.currentThread().getName()); } ).start(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("------list-size:"+list.size()); } }

d.管程法

/** * 测试:生产者消费者模型--》利用缓冲区解决:管程法 * 生产者、消费者、产品、缓冲区 */ public class ThreadContainer { public static void main(String[] args) { SynContainer syn = new SynContainer(); new Thread(new Productor(syn)).start(); new Thread(new Consumer(syn)).start(); } } // 缓冲区 class SynContainer{ // 设置容器的大小 Chicken[] chickens = new Chicken[2]; // 容器的计数器 int count = 0; //生产者放入产品 public synchronized void push(Chicken chicken) { // 如果容器满了,就需要等待消费者消费 if (count == chickens.length) { // 通知消费者消费,等待生产 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 如果没有满,我们就需要丢入产品 chickens[count] = chicken; count++; // 可以通知消费者消费了 this.notifyAll(); } // 消费者消费产品 public synchronized Chicken pop() { // 判断能否消费 if (count == 0) { // 等待生产者生产,消费者等待 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //如果可以消费 count--; Chicken chicken = chickens[count]; // 吃完了,通知生产者生产 this.notifyAll(); return chicken; } } // 生产者 class Productor implements Runnable{ SynContainer container; public Productor(SynContainer container) { this.container = container; } @Override public void run() { for (int i = 0;i < 10;i++) { System.out.println("----生产者生产了-->"+i+"的鸡"); container.push(new Chicken(i)); } } } // 消费者 class Consumer implements Runnable{ SynContainer container; public Consumer(SynContainer container){ this.container = container; } @Override public void run() { for(int i = 0;i < 10;i++) { System.out.println("---消费者消费了-->"+container.pop().numNo+"的鸡"); } } } // 产品 class Chicken{ int numNo; public Chicken(int numNo) { this.numNo = numNo; } }

e.使用Runnable创建线程池

/** * 使用线程池--Runnable */ public class ThreadPool implements Runnable{ public static void main(String[] args) { // 1.创建服务,创建线程池 ExecutorService service = Executors.newFixedThreadPool(10); // 2.执行 service.execute(new ThreadPool()); service.execute(new ThreadPool()); service.execute(new ThreadPool()); service.execute(new ThreadPool()); service.execute(new ThreadPool()); // 3.关闭链接 service.shutdown(); } @Override public void run() { System.out.println("---我是线程池:"+Thread.currentThread().getName()); } }
最新回复(0)