线程的基础知识

文章目录

目录

文章目录

一、线程的声明周期

二、线程的同步

一、synchronized同步的方法:(synchronized 关键字用于保护共享数据---->表示外面的线程不能进来)

二、通过Objectwait与notify

三丶线程的通信

四丶线程池

1.为什么使用线程池?

2、线程池的核心参数

3丶线程池执行任务的流程

4丶线程池的使用

总结



提示:以下是本篇文章正文内容,下面案例可供参考

一、线程的声明周期

示例:

线程的基础知识_第1张图片

 

二、线程的同步

一、synchronized同步的方法:(synchronized 关键字用于保护共享数据---->表示外面的线程不能进来

1、synchronized同步方法
  即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。

2、synchronized同步代码块
  即有synchronized关键字修饰的语句块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

package com.xhj.thread;
 
   /**
     * 线程同步的运用
     * @author XIEHEJUN
     */
    public class SynchronizedThread {
 
    class Bank {
            private int account = 100;
            public int getAccount() {
                return account;
            }
             /**
             * 用同步方法实现
             * 
             * @param money
             */
            public synchronized void save(int money) {
                account += money;
            }
             /**
             * 用同步代码块实现
             * 
             * @param money
             */
            public void save1(int money) {
                synchronized (this) {
                    account += money;
                }
            }
        }

	class NewThread implements Runnable {
            private Bank bank;
 
					public NewThread(Bank bank) {
                this.bank = bank;
            }
 
					@Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    // bank.save1(10);
                    bank.save(10);
                    System.out.println(i + "账户余额为:" + bank.getAccount());
                }
            }
        }
 
         /**
         * 建立线程,调用内部类
         */
        public void useThread() {
            Bank bank = new Bank();
            NewThread new_thread = new NewThread(bank);
            System.out.println("线程1");
            Thread thread1 = new Thread(new_thread);
            thread1.start();
            System.out.println("线程2");
            Thread thread2 = new Thread(new_thread);
            thread2.start();
        }
 
        public static void main(String[] args) {
            SynchronizedThread st = new SynchronizedThread();
            st.useThread();
        }
}

同步块同步块是通过锁定一个指定的对象,来对同步块中包含的代码进行同步----->同步块中包括的是线程操作的操作方法  不能多包括也不能少包括 

二、通过Objectwait与notify

当一个线程进入wait时,只能等另一个线程进入notify去释放他  从而可以达到有序进行 如果是多个的话就是去竞争  所以必须声明在synchronized里面 因为只能有一个线程去释放wait

不过lock和unlock就不一样了 他们俩 是线程直接进去然后锁住 然后自己出来解锁 依然可以和另一个线程去竞争再吃进入run方法里面  并且lock和unlock方法必须声明在try{}finally{}方法里面      不过lock里面可以把参数声明为(true)从而使其有序的进行

实现多个线程互斥访问临界区资源,Object类这几个方法必须配合synchronized来进行使用。

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。

notifyaAl():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。

三丶线程的通信

线程的通信其中一种就是交替打印   用wait 和 notify方法可以实现 

该处使用的url网络请求的数据。

四丶线程池

1.为什么使用线程池?

线程池提供了一种限制和管理资源(包括执行一个任务)。 每个线程池还维护一些基本统计信息,例如已完成任务的数量。
使用线程池的好处:

降低资源消耗。 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度。 当任务到达时,任务可以不需要的等到线程创建就能立即执行。
提高线程的可管理性。 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
 

2、线程池的核心参数

corePoolSize : 核心线程大小。线程池一直运行,核心线程就不会停止。
maximumPoolSize :线程池最大线程数量。非核心线程数量=maximumPoolSize-corePoolSize


keepAliveTime :非核心线程的心跳时间。如果非核心线程在keepAliveTime内没有运行任务,非核心线程会消亡。


workQueue :阻塞队列。ArrayBlockingQueue,LinkedBlockingQueue等,用来存放线程任务。


defaultHandler :饱和策略。ThreadPoolExecutor类中一共有4种饱和策略。通过实现RejectedExecutionHandler接口。


AbortPolicy : 线程任务丢弃报错。默认饱和策略。
DiscardPolicy : 线程任务直接丢弃不报错。
DiscardOldestPolicy : 将workQueue队首任务丢弃,将最新线程任务重新加入队列执行。
CallerRunsPolicy :线程池之外的线程直接调用run方法执行。
 

3丶线程池执行任务的流程

线程的基础知识_第2张图片

 


4丶线程池的使用

class NumberThread implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i%2==0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
class NumberThread1 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i%2!=0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        //1.提供指定数量的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        //设置线程池的属性

        //2.执行指定的线程的操作。需要提供实现Runnable接口或者Callable接口实现类的对象
        service.execute(new NumberThread());//适合使用于Runnable
        service.execute(new NumberThread1());//适合使用于Runnable
       // service.submit();//适合使用于Callable

        //关闭线程池
        service.shutdown();
    }
}

运行结果:

线程的基础知识_第3张图片


 

总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了线程的周期 ,线程的同步,线程的通信和线程池的初步了解

你可能感兴趣的:(java,开发语言)