3.异常、IO、多线程

  • 1.什么是进程,什么是线程?

进程是系统中已经运行的程序实体,是线程的容器,一个进程中可以包含多条线程。进程间相互独立,同一进程的各线程间共享地址空间和其他资源。
线程是程序中一条单一顺序的控制流,就是进程中真正做事的。
区别:地址空间和其他资源(如打开文件):进程间相互独立,同一进程的各线程间共享。
用法选择:
1.需要频繁创建销毁的优先使用线程,因为对进程来说创建和销毁一个进程的代价是很大的。
2.线程的切换速度快,所以在需要大量计算,切换频繁时使用线程,还有耗时的操作时用使用线程可提高应用程序的响应。
3.要更稳定安全时,选择进程 or 要速度时,选择线程。

  • 2.CPU的时间片轮

对于单核CPU来说,系统同一时刻只能干同一件事情,CPU会将它的时间分成很小的时间片轮,交替运行不同的程序,给人的错觉是同时在运行。

  • 3.线程的生命周期

在这里插入图片描述
注意:一个特殊的状态:就绪。具备了执行资格,但是还没有获取资源。

  • 4.线程的创建方式

a.继承Thread类,重写run方法
b.实现Runnable接口,重写run方法,启动时还是需要Thread包装一下。

/*   
 * 为什么需要多线程?
 * 更加充分的利用CPU资源
 */
public class ThreadDemo1 extends Thread
{
    public static void main(String[] args)
    {
        //java程序启动,就会默认创建一主(main)线程
        System.out.println("当前线:"+Thread.currentThread().getName());
        
        //创建线程
        //进入新建状态
        ThreadDemo1 t1 = new ThreadDemo1();
        t1.setName("A线程");
        //起动线程,进入就绪状态,等待cpu调度  (创建一条线程,得重新创建新的调用栈,内存分配等,过程是复杂的)
        t1.start();
        
        //main线程运行
        for (int i = 0; i < 100; i++)
        {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
    
    /**
     * 当线程启动(进入就绪状态)以后,cpu调度此线程就会默认执行这个里面代码
     */
    @Override
    public void run()
    {
        for (int i = 0; i < 100; i++)
        {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

public class ThreadDemo2 implements Runnable
{
    public static void main(String[] args)
    {
        //创建线程
        ThreadDemo2 td1 = new ThreadDemo2();
        //用实现Runnable线程创建的线程,还需要使用Thread包装一下才能起动
        Thread t1 = new Thread(td1,"A线程");
        t1.start();
        
        //再创建一个
        Thread t2 = new Thread(td1,"B线程");
        t2.start();
        
        //main
        for (int i = 0; i < 100; i++)
        {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 100; i++)
        {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
  • 5.线程如何停止
  1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止(常用)。

  2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend,也可能发生不可预料的结果)。

  3. 使用interrupt方法中断线程。

 -  使用退出标志
代码转载地址:https://blog.csdn.net/anhuidelinger/article/details/11746365
public class ThreadFlag extends Thread 
{ 
    public volatile boolean exit = false; 

    public void run() 
    { 
        while (!exit); 
    } 
    public static void main(String[] args) throws Exception 
    { 
        ThreadFlag thread = new ThreadFlag(); 
        thread.start(); 
        sleep(3000); // 主线程延迟3秒 
        thread.exit = true;  // 终止线程thread 
        thread.join(); 
        System.out.println("线程退出!"); 
    } 
} 
 - 使用stop方法终止线程 
 thread.stop(); 
 - 使用interrupt方法终止线程
代码转载地址:https://blog.csdn.net/anhuidelinger/article/details/11746365
public class ThreadInterrupt extends Thread 
{ 
    public void run() 
    { 
        try 
        { 
            sleep(10000);  // 延迟10秒 
        } 
        catch (InterruptedException e) 
        { 
            System.out.println(e.getMessage()); 
        } 
    } 
    public static void main(String[] args) throws Exception 
    { 
        Thread thread = new ThreadInterrupt(); 
        thread.start(); 
        System.out.println("在10秒之内按任意键中断线程!"); 
        System.in.read(); 
        thread.interrupt(); 
        thread.join(); 
        System.out.println("线程已经退出!"); 
    } 
} 
  • 6.线程同步

    多线程在竞争共享资源时,保证资源安全的一种手段。
    synchronized、lock 实现同步
    包裹的代码称之为临界区,每个对象都有并且仅有一把对象锁,只有拿到了锁的线程才能进入临界区,没有拿到锁的就在临界区外等待,这样就能保证同一时刻只有一个线程进入临界区。
    主要相同点:Lock 能完成 synchronized 所实现的所有功能
    主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。

线程异步:多线程可以同时对某个资源进行操作

-------------LOCK写法

public class LockTest {
    private Lock lock = new ReentrantLock();

    //需要参与同步的方法
    private void method(Thread thread){
        lock.lock();
        try {
            System.out.println("线程名"+thread.getName() + "获得了锁");
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            System.out.println("线程名"+thread.getName() + "释放了锁");
            lock.unlock();
        }
    }
}
-------------synchronized写法
第一种:
public void SynchronizedTestOne(){
			synchronized(this){//加锁,this代表当前拿到锁的对象
			System.out.println("SynchronizedTestOne");
			Thread.sleep(1000);
			System.out.println("线程名"+thread.getName() + "获得了锁");
		}
	}

第二种:
public synchronized void SynchronizedTestTwo() {
		System.out.println("SynchronizedTestTwo");
		try {
			Thread.sleep(1000);
			System.out.println("线程名"+thread.getName() + "获得了锁");
		} catch (InterruptedException e) {
		}
	}

PS:AJAX是异步。Ajax(Asynchronous Javascript And XML) = 异步 JavaScript 和 XML(标准通用标记语言的子集)。

  • 7.wait和sleep的区别
    wait是Object中定义的方法,需要手工调用notify()或者notifyAll()方法;
    wait表示当前线程在此对象上等待,wait的线程不会自动唤醒,必须由拿到同一个对象的锁的线程使用notify或notifyAll才会醒来;
    wait时,线程会释放锁;

    sleep是Thread类的一个静态方法,表示线程休眠,会自动唤醒;
    sleep休眠指定时间后,会自动唤醒;
    sleep时,线程不会释放锁;

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。-----------意思就是在锁内调用sleep,当前线程睡眠之后继续运行,其他线程还是进不来
wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。-----------在锁内调用此方法, 当前线程释放锁,其他线程能够去得到锁,能进入锁内。

  • 8.线程池
线程池可以让我们重用现有的线程,减少线程创建,消亡的资源的开销,并且可以有效的控制最大的并发数量,避免过多的线程竞争。
	  
创建一个可缓冲的线程池,如果当前的任务数量超过线程的数量,缓冲线程池会自动创建线程去处理任务,如果有线程长时间闲置,就会将其回收
	  ExecutorService executorSrv = Executors.newCachedThreadPool();
	  
	  创建一个单线程池
	  ExecutorService executorSrv = Executors.newSingleThreadExecutor();
	  
	  创建一个定长的线程池,线程池中的最大线程数量是5
	  ExecutorService executorSrv = Executors.newFixedThreadPool(5);

PS:现在还没怎么遇到线程池之类的问题,后面遇到了再完善此处… …

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值