javase-day09

aThreadCreate_01CreateDemo

package com.se.aThreadCreate;

/**
 * 线程的创建方式:  三种
 *   第一种: 使用Thread的实现类或者匿名内部类的方式来创建线程对象
 *           使用Runnable接口的方式来创建线程对象
 */

public class _01CreateDemo {
    public static void main(String[] args) {
        //创建一个线程对象  新建状态
        Thread t1 = new MyThread();
        //启动线程  处于就绪状态
        t1.start();


        //使用匿名内部类的方式,来实现Thread,来创建一个进程对象
        Thread t2 = new Thread() {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println(Thread.currentThread().getName() + "hello world" + i);
                }
            }
        };
        //启动线程t2,处于就绪状态
        t2.start();

    }
}

//实现Thread类型,自定义一个线程,实现1~100的打印
class MyThread extends Thread {
    //重写run方法 run方法就是来编写线程的任务代码的
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "" + i);
        }
    }
}

aThreadCreate_02CreateDemo

package com.se.aThreadCreate;

/**
 * 线程创建的三种方式:
 *  第二种: 使用Runnable接口的实现类或者匿名内部类的方式来创建线程对象
 */
public class _02CreateDemo {
    public static void main(String[] args) {
        //获取Runnable的实例对象
        Runnable task = new MyTask();
        //创建线程对象 调用构造器Thread (Runnable runnable),传入任务
        Thread t1 = new Thread(task);
        //启动线程,进入就绪状态
        t1.start();


        //使用匿名内部类或者lambda表达式 创建线程对象,计算100以内的奇数之和
        Thread t2 = new Thread(() -> {
            int sum = 0;
            for (int i = 1; i < 100; i += 2) {
                sum += i;
            }
            System.out.println("奇数之和为:" + sum);
        });
        t2.start();
    }
}


//自定义实现类 实现Runnable接口,计算100以内的偶数之和
class MyTask implements Runnable {
    //重现run方法: 线程的任务代码
    @Override
    public void run() {
        int sum = 0;
        for (int i = 2; i < 101; i += 2) {
            sum += i;
        }
        System.out.println("偶数之和为:" + sum);
    }
}

aThreadCreate_03CreateDemo

package com.se.aThreadCreate;

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

/**
 * 线程创建的三种方式:
 *  第三种:
 *    1. 先获取Callable对象,重写里面的call方法,call相当于run,但是call有返回值
 *    2. 在获取FutureTask对象,将Callable对象传入构造器
 *    3. 最后获取Thread对象,传入FutureTask对象
 *    4. 这种方式可以获得线程里的返回数据,进行其他操作。相比前两种方式,功能更强大一些
 */

public class _03CreateDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //Callable是函数式接口,里面的V call() 相当于Thread和runnable的run方法,即任务代码书写的位置
        Callable c1 = () -> {
            int sum = 0;
            for (int i = 2; i < 100; i += 2) {
                sum += i;
                Thread.sleep(100);
            }
            return sum;
        };
        //调用FutureTask的构造器,传入Callable对象
        FutureTask<Integer> futureTask = new FutureTask<>(c1);
        //创建Thread对象,传入FutureTask对象
        Thread t1 = new Thread(futureTask);
        t1.start();

        //获取线程执行结束后的结果  get()有阻塞所在线程的效果
        int result = futureTask.get();
        System.out.println(result);
    }
}

bConstructor_01ConstructorDemo

package com.se.bConstructor;

import java.util.Arrays;

/**
 * Thread的常用构造器:
 *  1. Thread(Runnable runnable)
 *  2. Thread(Runnable runnable, String name)
 *  3. Thread(String name)
 */

public class _01ConstructorDemo {
    public static void main(String[] args) {
        //使用Thread(Runnable runnable)创建一个线程对象
        //随机5个int数据[0~100],放入数组中,并冒泡排序,输出

        Thread t1 = new Thread(() -> {
            int[] arr = new int[5];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = (int) (Math.random() * 100);
            }
            for (int i = 0; i < arr.length - 1; i++) { // 减少一次循环次数
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            System.out.println(Arrays.toString(arr));
        });
        t1.start();
    }
}

bConstructor_02ConstructorDemo

package com.se.bConstructor;

/**
 * 构造器:
 *   Thread(Runnable runnable,String name)
 */

public class _02ConstructorDemo {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                //获取线程名字
                String name = Thread.currentThread().getName();
                for (int i = 0; i < 10; i++) {
                    System.out.println(name + ":" + i);
                }
            }
        };
        //调用两个参数的构造器,第二个参数是线程名称
        Thread t = new Thread(r, "线程1");
        t.start();
    }
}

bConstructor_03ConstructorDemo

package com.se.bConstructor;

/**
 * 第三个构造器:
 *  Thread(String name)
 */

public class _03ConstructorDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread("线程2"){
            public void run()
            {
                String name = this.getName();
                for (int i = 0; i < 10; i++) {
                    System.out.println(getName() + ":if you like" + i);
                }
            }
        };
        t1.start();
    }
}

cPropertyMethod_PropertyMethodDemo

package com.se.cPropertyMethod;

/**
 * 线程常用的属性方法
 */

public class PropertyMethodDemo {
    public static void main(String[] args) {
        // main方法:本质上就是一个线程

        //1. 获取当前线程的对象
        Thread currnt= Thread.currentThread();
        //2. 获取当前线程的名称
        String name= currnt.getName();
        //3. 获取当前线程的唯一标识符
        long id= currnt.getId();
        //4. 获取当前线程的优先级
        int priority= currnt.getPriority();
        //5. 获取当前线程的状态
        Thread.State state= currnt.getState();
        //6. 查看当前线程是否存活
        boolean isAlive= currnt.isAlive();
        //7. 查看当前线程是否被打断
        boolean isInterrupted= currnt.isInterrupted();
        //8. 查看当前线程是否是守护线程
        boolean isDaemon= currnt.isDaemon();

        System.out.println("当前线程的名称:"+name);
        System.out.println("当前线程的唯一标识符:"+id);
        System.out.println("当前线程的优先级:"+priority);
        System.out.println("当前线程的状态:"+state);
        System.out.println("当前线程是否存活:"+isAlive);
        System.out.println("当前线程是否被打断:"+isInterrupted);
        System.out.println("当前线程是否是守护线程:"+isDaemon);
    }
}

dDaemon_DaemonDemo

package com.se.dDaemon;

/**
 *  守护线程:
 *    1. 线程要么是守护线程,要么是前台线程
 *    2. 前台线程:在表面运行的,能看到的  or daemon的值是false
 *    3. 后台线程:就是守护线程:在运行过程中,不可见  or daemon的值是true
 *
 *    tips: 所有的前台线程都结束了,后台线程也会立即结束
 */

public class DaemonDemo {
    public static void main(String[] args) {
        //第一个线程: rose: i jump *10  jump
        Thread rose = new Thread( () -> {
            for (int i = 0; i < 10; i++) {
                System.out.println("i jump");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("jump");
        });
        //第二个线程: jack: you jump with rose
        Thread jack = new Thread( () -> {
            for (int i = 0; i < 100; i++) {
                System.out.println("you jump,i jump");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //jack 线程设置为守护线程,rose jump ,jack stop
        jack.setDaemon(true);
        //启动线程
        rose.start();
        jack.start();
    }
}

eLifeMethod_01SleepDemo

package com.se.eLifeMethod;

/**
 * static void sleep(long time)方法
 *  解析:
 *       线程的睡眠方法,可以让当然线程进入休眠状态,进入阻塞状态,不再占用CPU资源
 *       时间单位是ms,休眠时一过,立马进入就绪状态(等待调度器分配时间片段)
 *
 *       tips: 休眠时间内可能会被异常中断,因此要处理异常 InterruptedException
 *
 *  static void sleep(long time, int nanos)
 *  两个参数的方法:
 *    time: 单位是毫秒
 *    nanos: 单位是纳秒,取值范围是0-999999
 */

public class _01SleepDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread("download"){
            public void run(){
                for (int i = 1; i < 10; i++) {
                    System.out.println("下载中..."+ (i*10)+"%");
                    //使用休眠方法,模拟下载
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.start();
    }
}

eLifeMethod_02YieldDemo

package com.se.eLifeMethod;

/**
 * static void yield():
 *  解析:
 *      线程的礼让方法,表示让出CPU的使用权,会进入就绪状态,
 *      不过下个时间片还是竞争
 *
 */

public class _02YieldDemo {
    public static void main(String[] args) {
        Thread t1 = new Thread("Thread-A"){
            public void run(){
                for (int i = 0; i < 10; i++){
                    System.out.println(getName() + ":" + i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };

        Thread t2 = new Thread("Thread-B"){
            public void run(){
                for (int i = 0; i < 10; i++){
                    //打印5之前让时间片
                    if (i == 5){
                        //执行到上一行时,cpu正在被Thread-B占用,然后礼让,之后进入就绪状态
                        //下一次cpu时间片分配依然抢占
                        Thread.yield();
                    }
                    System.out.println(getName() + ":" + i);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };
        t2.start();
        t1.start();
    }
}

eLifeMethod_03JoinDemo

package com.se.eLifeMethod;

/**
 * void join():
 *  解析:
 *      另一个线程加入方法,此时当前线程就会处于阻塞状态,
 *      直到另一个线程执行完毕,当前线程才会继续执行。
 *
 *  案例演示:
 *    图片下载线程
 *    图片显示线程
 *
 *    先下载,再显示
 */

public class _03JoinDemo {
    public static void main(String[] args) {
        Thread download = new Thread("download") {
            public void run() {
                for (int i = 0; i < 101; i++) {
                    System.out.println(getName() + ":下载中" + i+"%");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(getName() + ":下载完毕");
            }
        };
        Thread show = new Thread("show") {
            public void run() {
                try {
                    //当前线程是显示线程,显示应该在下载之后,因此用john方法阻塞显示线程
                    download.join();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                for (int i = 0; i < 101; i++) {
                    System.out.println(getName() + ":显示中" + i+"%");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(getName() + ":显示完毕");
            }
        };
        download.start();
        show.start();

    }
}

eLifeMethod_04InterruptDemo

package com.se.eLifeMethod;

/**
 * void interrupted():   无static 用对象调用
 *   解析: 线程中断,打断方法,表示当前线程打断另一个线程。
 *
 *     tips:是在当前线程中调用另一个线程的打断方法
 */

public class _04InterruptDemo {
    public static void main(String[] args) {
        Thread lin = new Thread("林永健") {
            public void run() {
                System.out.println(getName() + "说:开始睡觉");
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(getName() + "说:干嘛呢!干嘛呢!");
                }
            }
        };
        Thread huang = new Thread("黄宏") {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(getName() + "说:" + (i + 1) + "个80");
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(getName() + "说:搞定了");
                //打断lin的睡觉
                lin.interrupt();
            }
        };
        //启动
        huang.start();
        lin.start();
    }
}

fSourceSafe_01SafeDemo

package com.se.fSourceSafe;

public class _01SafeDemo {
    public static void main(String[] args) {
        Runnable desk = new Desk();
        Thread xiaoming = new Thread(desk,"小明");
        Thread xiaohong = new Thread(desk,"小红");

        xiaoming.start();
        xiaohong.start();
    }
}

class Desk implements Runnable {
    //静态属性,豆子数量,初始值10个
    private static int beancount = 10;

    //拿走豆子,一次一个
    public void take() {
        beancount--;
    }

    //定义线程的任务,取走豆子,一个一个的拿走
    public void run() {
        while(beancount >0){
            /*
              在桌子上只剩下一个豆子的时候,两个线程恰巧都执行到条件判断
              1>0 成立,都进入循环体,两个进程各取走一个豆子,此时豆子变成-1个
              明显不合理,出现安全隐患线程不安全
             */
            try {
                //增加出现安全隐患的概率
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            take();
            System.out.println(Thread.currentThread().getName()+"拿走一个豆子,剩下的是"+beancount);
        }
    }
}

fSourceSafe_02SynchronizedDemo

package com.se.fSourceSafe;

/**
 * 锁机制的介绍:
 *   针对于具有临界资源安全隐患问题的解决方式,就是引入锁机制
 *   1. 锁机制的作用,将异步的代码块变成同步的代码块。
 *   2. 语法:
 *      synchronized(锁对象的地址){
 *          需要同步的代码块(如果不同步就会出现安全隐患)
 *      }
 *   3. 任何java对象都苦作为锁
 *   4. 同步的代码块,在可能的情况下尽量缩小范围,提高其他代码的并发效率
 *   5. 运行逻辑:
 *      当一个线程执行到{}里,就表示该线程获取了锁对象,其他线程都必须等待,
 *      直到线程A执行完同步代码块,会自动释放锁对象。其他线程有机会获取锁对象,
 *      谁获取到锁对象,谁就执行同步代码块。
 */

public class _02SynchronizedDemo {
    public static void main(String[] args) {
        Runnable desk1 = new Desk1();
        Thread xiaoming = new Thread(desk1, "小明");
        Thread xiaohong = new Thread(desk1, "小红");

        //启动线程
        xiaoming.start();
        xiaohong.start();
    }
}

class Desk1 implements Runnable {
    //静态属性,豆子数量,初始值10个
    private static int beancount = 10;

    //拿走豆子,一次一个
    public void take() {
        beancount--;
    }

    //定义线程的任务,取走豆子,一个一个的拿走
    public void run() {
        while (true) {
            try {
                //增加出现安全隐患的概率
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //将具有安全隐患问题的代码放入{},因为两个线程都操作同一个桌子,因此this是锁对象
            synchronized (this) {
                if (beancount > 0) {
                    take();
                }
            }
            System.out.println(Thread.currentThread().getName() + "拿走一个豆子,剩下的是" + beancount);
            if (beancount <= 0) {
                break;

            }
        }
    }
}

fSourceSafe_03SynchronizedDemo

package com.se.fSourceSafe;

/**
 * Synchronized的作用域
 *  1. 如果使用了synchronized(锁对象){
 *            代码块
 *     }关键字,那么同步块就是{}里的代码
 *  2. synchronized可以作用在非静态方法上  锁对象是this
 *  3. synchronized可以作用在静态方法上   锁对象是类名.class
 */

public class _03SynchronizedDemo {
    public static void main(String[] args) {
        Blackboard b1 = new Blackboard();
        Thread xiaoming = new Thread(b1,"小明");
        Thread xiaohong = new Thread(b1,"小红");

        xiaoming.start();
        xiaohong.start();
    }
}

class Blackboard implements Runnable {
    private static int apple = 10;

    public void run() {
        while (true) {
            take();
            System.out.println(Thread.currentThread().getName()+"拿走一个apple,剩下"+apple);
            if (apple == 0) {
                break;
            }
        }
    }

    //可以对非静态方法进行上锁。锁对象是this
    public synchronized void take() {
        if (apple > 0) {
            apple--;
        }
    }
}

zExercise_Exercise01

package com.se.zExercise;

/**
 * 实例化两个线程,同时对一个数字进行操作。
 * 一个线程对这个数字进行加1,另外一个线程对这个数字进行减一。
 * 输出每一次的操作之后的这个数字的值。
 */

public class Exercise01 {
    public static int num = 0;

    public static void main(String[] args) {

        Thread t1 = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("t1:" + num++);
            }
        });
        Thread t2 = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("t2:" + num--);
            }
        });
        t1.start();
        t2.start();
    }
}

zExercise_Exercise02

package com.se.zExercise;

/**
 * 有五个人同时过一个独木桥,一个独木桥同时只能允许一个人通过。
 * 每一个人通过独木桥的时间是随机在[5,10]秒,输出这个独木桥上每一个人的通过详情,
 * 例如:张三开始过独木桥了..,张三通过独木桥了!
 */

public class Exercise02 {

    private static final Object bridgeLock = new Object();

    public static void main(String[] args) {
        People[] persons = new People[5];
        for (int i = 0; i < persons.length; i++) {
            persons[i] = new People(i + 1);
            persons[i].start(); // 启动线程
        }
    }

    static class People extends Thread {
        private final int id;

        public People(int id) {
            this.id = id;
        }

        @Override
        public void run() {
            dmq(id);
        }

        private void dmq(int peopleId){
            synchronized (bridgeLock) { // 确保同一时刻只有一个线程可以执行过桥操作
                System.out.println(  peopleId + " 开始过独木桥了");
                try {
                    Thread.sleep((long)(Math.random() * 600 + 500));
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println( peopleId + " 通过独木桥了");
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值