3.31 线程大总结

package com.qiku.yrc.work24;



public class W1 {
    /**
     * 1、 使用synchronized 、wait() 、notifyAll()方法实现 生产者消费者模型

     */
    private  static  int number=0;
    private  static  final  int FULL = 30;
    private  static  String LK = "LOCK";
    class  Producer implements Runnable{
        @Override
        public void run() {
            while (true){
            synchronized (LK){
                if (number==FULL) {
                    try {
                        LK.wait(); //就绪状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                number++;//生产商品
                System.out.println(Thread.currentThread().getName()
                        + "生产者生产,目前共有商品的个数: " + number);
                LK.notifyAll();//唤醒消费者线程
            }
        }}
    }
    class  Consumer implements Runnable{
        @Override
        public void run() {
            while(true){
            synchronized (LK){
                if (number==0) {
                    try {
                        LK.wait(); //就绪状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                number--;//生产商品
                System.out.println(Thread.currentThread().getName()
                        + "生产者生产,目前共有商品的个数: " + number);
                LK.notifyAll();//唤醒消费者线程
            }
        }}
    }

    public static void main(String[] args) {
        W1 w1 = new W1();
        Producer producer = w1.new Producer();//创建生产者对象
        Consumer consumer = w1.new Consumer();//创建消费者对象
        Thread t1 = new Thread(producer);// 生产者线程
        Thread t2 = new Thread(consumer);// 消费者线程
        t1.start();
        t2.start();
    }
}
package com.qiku.yrc.work24;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

//使用3种不同的方式创建线程
public class W2 extends Thread{
    public static void main(String[] args) throws Exception {
       W2 t1= new W2();
       W2 t2 = new W2();
       t1.start();
       t2.start();
       t1.join();
       t2.join();
        System.out.println("方法一 结束 ");

        //方法二 匿名内部类 创建
        new Thread(new Runnable() {
             int sum2=0;
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    sum2+=i;
                }
                System.out.println(Thread.currentThread().getName()+"  1000以内的和为:" +
                        ""+sum2);
            }
        }).start();


//   new Thread() {
//        @Override
//        public void run() {
//            for (int i = 0; i < 1000; i++) {
//                System.out.println(
//                        //获取线程的名字
//                        Thread.currentThread().getName() + i);
//            }
//        }
//    }).start();
//}
//}
    // 方法三 Callable  创建MyCallable 、FutureTask对象  支持 泛型 重写 call方法
Mathod3 mathod3 = new Mathod3();
        //将myCallable  指定的任务 交给 task
        FutureTask<Integer> task= new FutureTask<>(mathod3);
        //使用task为参数,创建Thread对象
        Thread thread3 = new Thread(task);
        thread3.start();

    }

    @Override
    public void run() {
        super.run();
        int sum=0;
        for (int i = 0; i < 100; i++) {
            sum+=i;
        }
        System.out.println(Thread.currentThread().getName()+"  100以内的和为:" +
                ""+sum);
    }

    }
    class  Mathod3 implements Callable<Integer>{

        @Override
        public Integer call() throws Exception {
            int sum3=0;
            for (int i = 0; i < 100; i++) {
                sum3+=i;
            }
            System.out.println(Thread.currentThread().getName()+"  100以内的和为:" +
                    ""+sum3);
            return sum3;
        }
    }
package com.qiku.yrc.work24;



import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

//     * 3、 测试3种不同线程池,体会下区别
public class W3 {
    public static void main(String[] args) {
        //可存储的缓冲池
        ExecutorService executorService = Executors.newCachedThreadPool();
        W3 w3 = new W3();//创建线程对象
        //向线程池中 布置任务
        //提交
        executorService.submit((Runnable) w3);
        //关闭线程池
        executorService.shutdown();

    }
}
package com.qiku.yrc.work24;

public class W4 {
//         * 4、 默写出线程的线程的生命周期,以及不同状态做什么事情?
public static void main(String[] args) {
//    3 线程的相关的方法
//
//```java
//    Thread()  // 线程的无参构造器
//    Thread(String name)  // 可以指定线程名字的构造器
//    Thread(Runable target)  // 根据自定义的对象 创建线程
//
//    void run() // 线程启动后具体执行的方法
//    void start() // 启动线程的方法 ,使线程进入就绪状态  等待被分配时间片
//```
//
//## 4、线程的生命周期
//
//```java
//    新建状态new - 使用new关键字创建之后进入的状态,此时线程并没有开始执行。
//    就绪状态runable - 调用start方法后进入的状态,此时线程还是没有开始执行。
//    运行状态running - 使用线程调度器调用该线程后进入的状态,此时线程开始执行,
//    当线程的时间片执行完 毕后任务没有完成时回到就绪状态。
//    消亡状态dead - 当线程的任务执行完成后进入的状态,此时线程已经终止。
//    阻塞状态blocked - 当线程执行的过程中发生了阻塞事件进入的状态,如:sleep方法。
//    阻塞状态解除后进入就绪状态。
//
//    -------
//            使用new关键字创建线程对象   -  线程进入  新建状态                           --- 不执行
//    调用start()                   - 线程进入  就绪状态(等待被分配时间片)     --- 不执行
//    当线程分配到了时间时间片  - 线程进入   运行状态     ---- 执行run()方法
//    当时间片使用完毕之后,如果线程线程没结束  则回到  就绪状态(等待被分配时间片)    --- 不执行
//    如果线程任务执行完毕  - 线程进入   消亡状态
//
//    在运行状态时,若发生导致阻塞事件(sleep(times) , wait()  ,join() )
//            - 线程进入   阻塞状态(等待阻塞结束)   --  不执行
//    当阻塞状态结束时,则进入  就绪状态(等待被分配时间片)     --- 不执行
//
//
//
//```
//
//## 5、获取线程的信息 & 常用方法
//
//```java
//    long getId()   // 获取线程的ID  编号
//    String getName() // 获取线程的名字
//    void setName(String name ) // 设置线程的名字
//    static Thread currentThread() // 获取正在运行的线程对象
//
//            -----
//
//    static void yield() // 使线程进入  就绪状态(等待被分配时间片) 不是阻塞
//    static void sleep(long times) //使线程进入休眠(阻塞)状态
//    int getPriority()  //获取线程的优先级 默认 5
//    void setPriority(int newPriority) //设置优先级  优先级越高 不一定先执行,只是获取时间片的机会更多
//
//    void join() // 等待该线程结束
//    void join(long times) // 等待该线程times毫秒
//
//    boolean isDaemon() // 判断是否是守护线程
//    void setDaemon(boolean on)// 设置守护线程
//```
//
//## 6 用户线程和守护线程
//
//```java
//    正常我们创建的线程  都是用户线程
//    用户线程和守护线程基本没什么区别  一样的
//    守护线程:唯一的区别,就是它会等其他线程全部结束之后,守护也会结束(不论守护线程是否执行完毕)
//    也就是如果内存中只剩下守护线程,守护线程则会立刻结束
//
//
//    如果希望某个线程最后结束,可以设置为守护线程
//    t.setDaemon(true);
//    注意:必须在线程启动之前设置,否则会报异常  IllegalThreadStateException
//```
//
//
//
//## 7 线程同步机制
//
//```java
//    当多个线程同时访问同一种共享资源时,可能会造成数据的覆盖等不一致性问题,
//    此时就需要对线程之间进行通信和协调,该机制就叫做线程的同步机制。
//
//    多个线程并发读写同一个临界资源时会发生线程并发安全问题。
//
//    异步操作:多线程并发的操作,各自独立运行。
//
//    同步操作:多线程串行的操作,先后执行的顺序。
//
//    ------
//
//            由程序结果可知:当两个线程同时对同一个账户进行取款时,导致最终的账户余额不合理。
//
//    引发原因:线程一执行取款时还没来得及将取款后的余额写入后台,线程二就已经开始取款。
//
//    解决方案:让线程一执行完毕取款操作后,再让线程二执行即可,将线程的并发操作改为串行操作。
//
//    经验分享:在以后的开发尽量减少串行操作的范围,从而提高效率。
//
//
//
//
//    原子性:
//    取钱步骤: 1、获取余额 2、余额扣减  3、修改余额
//    上面3个步骤,在程序的执行过程中,是可以互相独立  不具备原子性
//    原子性是说:把这单个步骤当成一个整体,要都执行,要么一个也不执行
//
//    在Java语言中使用synchronized关键字来实现同步/对象锁机制从而保证线程执行的原子性,
//
//    具体方式如下:
//    1、使用同步代码块的方式实现部分代码的锁定,格式如下:
//    synchronized(对象名) {
//        编写所有需要锁定的代码;
//        语句1
//                语句2
//        语句3
//    }
//    对象名 : 如果仅仅锁定  一个代码块,写什么对象的名字  都行
//    如果想锁定多个代码块  ,只需要写同一个对象的名字即可(保证是同一个对象锁)
//
//
//    2、使用同步方法的方式实现所有代码的锁定。 直接使用synchronized关键字来修饰整个方法即可
//    public synchronized void show(){
//        //方法体
//    }
//
//
//    该方式等价于:
//    synchronized(this) {
//        整个方法体的代码
//    }
//
//
//    当我们对一个静态方法加锁,如:
//    public synchronized static void xxx(){
// ....
//    }
//    那么该方法锁的对象是类对象。每个类都有唯一的一个类对象。获取类对象的方式:类名.class。
//    静态方法与非静态方法同时使用了synchronized后它们之间是非互斥关系的。
//    原因在于:静态方法锁的是类对象而非静态方法锁的是当前方法所属对象。
//
//    class Peroson{}
//
//    Person p1 = new Person();
//    p1 ===>   Peroson类的   对象  (可以有无数多个)
//    Perosn.class ===> Person类的   类对象 (唯一性)
//
//
//
//```
//
//
//
//###  注意事项
//
//```java
//    使用synchronized保证线程同步应当注意:
//    多个需要同步的线程在访问同步块时,看到的应该是同一个锁对象引用。
//    在使用同步块时应当尽量减少同步范围以提高并发的执行效率。
//
//
//    StringBuffer类是线程安全的类,但StringBuilder类不是线程安全的类。
//    Vector类和 Hashtable类是线程安全的类,但ArrayList类和HashMap类不是线程安全的类。
//    Collections.synchronizedList() 和 Collections.synchronizedMap()等方法实现安全。
//```



}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值