【Java-6】多线程-3

package java4;

/**
 *  使用同步机制将单例模式中的懒汉式改为线程安全的
 *
 * @author Baobao
 * @create 2021-08-02  8:25
 */
public class BankTest {
}
class Bank{
    private Bank(){

    }
    private static Bank instance=null;

    public static Bank getInstance(){
        //方式1:效率稍差
//        synchronized (Bank.class){
//            if(instance==null){
//                instance=new Bank();
//                return instance;
//            }
//            return instance;
//        }
        //方式2:
        if(instance==null){
            synchronized (Bank.class){
                if(instance==null){
                    instance=new Bank();
                    return instance;
                }
            }
        }
        return instance;
    }
}
package java4.exer1;

/**
 * 线程通信的例子:交替打印1~100,两个线程
 *
 * 三个方法:
 * wait();一旦执行,线程就进入阻塞,并释放同步监视器
 * notify();一旦执行此方法,就会唤醒被wait的线程,如果有多个线程wait,就唤醒优先级高的
 * notifyAll();唤醒所有的wait的线程
 *
 *
 * 注意点:wait,notify和notifyAll只能出现在同步代码快或者是同步方法中
 * 这三个方法的调用者必须是同步代码快或同步方法中的同步监视器!!!!!否则会出现异常
 * 这三个方法是定义在java.lang.object类包中的
 *
 *
 * 面试题:sleep和wait方法的异同?
 * 1.相同点:都可以让当前线程进入阻塞状态
 * 2.不同点:1)两个方法声明的位置不一样,sleep在Thread中,wait在object中
 *          2)调用的范围,要求不一样,sleep没什么要求,wait一定要在同步代码块或者是同步方法中
 *          3)wait会释放锁,sleep不会
 *
 *
 *
 * @author Baobao
 * @create 2021-08-02  16:17
 */
class Number implements Runnable{
    private int number;
    @Override
    public void run() {
        while(true){
            synchronized (this){
                notify();
                if(number<=100){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+":"+number);
                    number++;
                    try {//使得调用如下wait方法的线程进入阻塞状态
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }
            }

        }
    }
}
public class CommnuicationTest {
    public static void main(String[] args) {
        Number num=new Number();
        Thread t1=new Thread(num);
        Thread t2=new Thread(num);

        t1.setName("线程1");
        t2.setName("线程2");
        t1.start();
        t2.start();
    }
}
package java4.exer1;

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

/**
 *
 * 创建线程的方式三:实现Callable接口的方式----jdk5.0新增的
 *
 * 如何理解callable比runnable更强大?(实现多线程)
 * 1.call方法可以有返回值
 * 2.call方法可以抛出异常,被外面的操作捕获,获取异常信息
 * 3.callable是支持泛型的
 *
 *
 *
 *
 * @author Baobao
 * @create 2021-08-02  18:32
 */

class NumberThread implements Callable{

    @Override
    public Object call() throws Exception {
        int sum=0;
        for (int i = 1; i <=100 ; i++) {
            if(i%2==0){
                System.out.println(i);
                sum+=i;
            }
        }
        return sum;
    }
}
public class ThreadNew {
    public static void main(String[] args) {
        //创建callable接口实现类的对象
        NumberThread numberThread=new NumberThread();
        //将此callable接口的实现类对象传入futuretask构造器中,去创造futuretask对象
        FutureTask fu = new FutureTask(numberThread);
        //将futuretask对象作为参数传入thread中,调用start方法
        new Thread(fu).start();
        try {
            //get的返回值即为futuretask的构造器参数的callable实现类重写的call方法的返回值
            Object sum=fu.get();
            System.out.println(sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
package java4.exer1;

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

/**
 *
 * 创建线程的方式4:线程池
 * 好处1:提高响应速度
 * 好处2:降低资源消耗(重复利用线程,不用每次都创建新的)
 * 好处3:便于管理
 *
 * @author Baobao
 * @create 2021-08-02  20:52
 */

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);
            }
        }
    }
}
class NumberThread2 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) {
        //提供指定线程数量的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        ThreadPoolExecutor service1=(ThreadPoolExecutor)service;
        //设置线程池的属性
        //System.out.println(service.getClass());
        service1.setCorePoolSize(15);

        //提供实现runnable或者callable接口的实现类对象
        service.execute(new NumberThread1());//适合适用于runnable
        service.execute(new NumberThread2());
//        service.submit();//适合适用于callable
        service.shutdown();
    }
}

上一篇:如何评估计算机的性能?


下一篇:hash长度扩展攻击