java基础————多线程

本文详细介绍了Java多线程的基本概念、JVM运行原理、实现方式、调度机制、线程控制等核心内容,包括进程与线程的区别、多线程的意义、JVM启动线程、线程调度模型、如何获取线程名称与优先级、线程控制方法如休眠、中断、礼让等,以及同步代码块和多线程数据安全的保证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

----------- android培训java培训、java学习型技术博客、期待与您交流!------------

 

 

多线程

        
        a.进程的概述和多进程的意义

            进程:            就是正在执行的应用程序.
            多进程的意义:    提高CPU的使用率.
                            
                            如果一个计算机上同时启动了听音乐的进程和打游戏的进程,那么这两个进程是同时在执行吗?
                            不是,因为CPU在一个时间点上只能执行一个任务.而我们看到的像是在同时执行,那是因为CPU在这两个进程之间进行高效的切换.

        b.线程的概述和多线程的意义:
            
            线程: 一个应用程序可以有多个任务,而每一个任务可以看做成一个线程.如果一个应用程序只有一个任务,那么这个应用程序,就属于单线程应用程序.
                  如果一个应用程序存在朵儿任务,那么这个应用程序就属于多线程应用程序.
            多线程的意义:    多线程的存在是提供了应用程序的使用率.
                    
                            每一个应用程序在执行的时候都是在依赖于线程抢占CPU的时间片(执行权) , 如果有一个应用程序A只有一个线程,而另一个应用程序B
                            存在多个线程,那么那个应用程序抢占到CPU的执行权的概率大呢?  多个线程的应用程序B. 但是一定就是B应用程序抢占到CPU的执行权
                            吗? 不一定,所以我们多线程在执行的时候具有随机性.

        c.JVM运行原理以及JVM启动的线程探讨
            
            JVM的运行原理:    我们在使用java命令在运行一个程序的时候,其实是启动了JVM,而JVM的启动相当于一个进程.而同时这个进程会启动
                            一个线程,通过这个线程来调用main方法,而这个线程就是我们的主线程.
            JVM的启动是多线程的吗?
                        是多线程的.因为JVM至少启动了两个线程,一个是主线程 , 一个是垃圾回收线程.

        d: 实现多线程

            两种方式:
                第一种方式的步骤:
                    a: 创建一个类,然后让这个类去继承Thread类
                    b: 复写run方法(run方法中封装的都是要被线程执行的代码, run方法中代码的特点: 比较耗时的代码)
                    c: 创建a中定义的类的对象
                    d: 启动线程(启动线程使用的是start()方法)

                   

                  public class MyThread extends Thread {
                        public void run() {                
                            for(int x = 0 ; x < 100 ; x++){
                                System.out.println(x);
                            }
                        }
                    }
                    
                    MyThread t1 = new MyThread() ;
                    MyThread t2 = new MyThread() ;

                    t1.start() ;
                    t2.start() ;

 

 


                第二种方式的步骤:
                    a: 创建一个类,然后让这个类去实现Runnable接口
                    b: 复写run方法
                    c: 创建a中定义的类的对象
                    d: 创建Thread类的对象,然后把c中的对象作为参数传递
                    e: 启动线程

                  

 

 

                public class MyThread implements Runnable {
                        public void run() {                
                            for(int x = 0 ; x < 100 ; x++){
                                System.out.println(x);
                            }
                        }
                    }

                    MyThread my = new MyThread() ;

                    Thread t1 = new Thread(my) ;
                    Thread t2 = new Thread(my) ;
                    
                    t1.start() ;
                    t2.start() ;

 

 


        线程调度:
            
            调度模型:
                a: 分时调度            就是给每一个线程分配指定的时间进行执行
                b: 抢占式调度        优先的执行优先级高的线程,如果线程的优先级相同,那么就随机执行一个.每一个线程应该都存在一个默认的优先级.
                                    而java语言采用的就是抢占式调度
                
                如何获取线程的优先级?    
                    public final int getPriority():                    获取线程的优先级(线程的默认优先级是: 5)
                    public final void setPriority(int newPriority): 给线程设置优先级(存在一个范围这个范围是1-10)
                
        线程名称的问题:

            如何获取线程的名称?            public final String getName()
            如何给线程设置名称?            public final void setName(String name), 也可以通过构造方法进行设置
            如何获取主线程的名称?        获取到当前正在执行的线程,然后在获取线程名称.如何获取到当前正在执行的线程.
                在Thread类中存在一个静态的方法:
                                        public static Thread currentThread():获取当前正在执行的线程.

        线程控制:
            线程休眠(掌握):        public static void sleep(long time) ;
            线程加入(了解):        public final void join();                等待该线程终止. 等待该线程执行完毕以后在执行其他的线程
            线程礼让(了解):        public static void yield():                暂停当前正在执行的线程对象,并执行其他线程。
            守护线程(了解):        public final void setDaemon(boolean on):把指定的线程设置成一个守护线程.当执行的线程都是守护线程的时候,JVM停止运行
            线程中断(掌握):        
                                public final void stop():        停止线程的运行
                                public void interrupt():        打断阻塞状态.    继续执行下面的代码,但是该方法会抛出异常.

线程休眠案例:                                    

 

 

 

/**
 * 线程控制之线程休眠:
 *         public static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),
 */
public class ThreadDemo {
    
    public static void main(String[] args) {
        
        // 创建线程对象
        MyThread t1 = new MyThread() ;
        
        // 给线程设置名称
        t1.setName("张三") ;
        
        // 启动线程
        t1.start() ;
        
    }

}

 

public class MyThread extends Thread {

	@Override
	public void run() {
		
		for(int x = 0 ; x < 100 ; x++) {
			
			// 线程休眠
			try {
				Thread.sleep(2000) ;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(getName() + "----" + x);
		}
		
	}
	
}

 

 

 

线程中断案例:       

 

 

 

 

                                    

public class Test1 {
    /**
     * 线程控制之线程中断: public final void stop(): 中断线程 public void interrupt(): 中断线程。
     * 如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法, 或者该类的
     * join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,
     * 则其中断状态将被清除,它还将收到一个 InterruptedException。
     */

    public static void main(String[] args) {

        // 创建线程对象
        MyThread t1 = new MyThread();

        // 设置线程名称
        t1.setName("宋承宪");

        // 启动线程
        t1.start();

        try {
            Thread.sleep(3000);

            // 中断线程t1
             t1.stop() ;
        

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}

 

public class MyThread extends Thread {

	@Override
	public void run() {
		
		System.out.println("线程开始执行了.......");
		
		try {
			Thread.sleep(100000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("线程任务结束了......");
		
	}
	
}




数据安全的一个保证:
        
        可以使用同步代码块:
            格式:
                synchronized(对象){
                    要被同步的代码 ;
                }    
            同步代码块在保证数据的安全性主要依赖这个对象,要求使用的对象必须是同一个.这个对象可以看做成一把锁.
        
        同步代码块的好处:    可以保证数据的安全性
        同步代码块的弊端:    效率降低了

    同步代码块以及同步方法和静态同步方法的锁对象的问题:

        同步代码块的锁对象:        是任意的对象
        同步方法的锁对象:        是this
        静态同步方法的锁对象:    是该类对应的字节码文件对象.

 

 

 

 

案例:需求。有一百张电影票,三个窗口同时卖票。代码实现

 

 

 

 

 

public class SellTickets implements Runnable {
	
	// 定义票的数量
	private static int num = 100 ;
	private static final Object obj = new Object() ;
	private int n = 0 ;
	
	@Override
	public void run() {
		
		while(true) {
			
			if(n % 2 == 0){
				synchronized(SellTickets.class) {
					
					if(num > 0) {
						
						try {
							Thread.sleep(100) ;
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						
						System.out.println(Thread.currentThread().getName() + "正在出售第" + (num--) + "张票");
					}
					
				}
			}else {
				sellTickets() ;
			}
			
			n++ ;
		}
	}

	// 静态同步方法
	public static synchronized void sellTickets() {
			
		if(num > 0) {
			
			try {
				Thread.sleep(100) ;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			System.out.println(Thread.currentThread().getName() + "正在出售第" + (num--) + "张票");
		}
	}
}


实现类

 

 

public class SellTicketsDemo {
    
    public static void main(String[] args) {
        
        // 创建SellTickets对象
        SellTickets st = new SellTickets() ;
        
        // 创建Thread对象
        Thread t1 = new Thread(st , "窗口1") ;
        Thread t2 = new Thread(st , "窗口2") ;
        Thread t3 = new Thread(st , "窗口3") ;
        
        // 启动线程
        t1.start() ;
        t2.start() ;
        t3.start() ;
        
    }

}

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值