zoukankan      html  css  js  c++  java
  • java线程与线程安全的单例模式

    四种使用线程的方式:继承Thread、实现Runnable接口、实现Callable接口、使用线程池(ThreadPool);代码:

    package com.jay.contact;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.locks.ReentrantLock;
    
    //视频教程 https://www.bilibili.com/video/BV1Kb411W75N?p=436
    public class ThreadTest {
        public static void main(String[] args) {
            // 方式一 继承 Thread 类
    //        ThreadTest1 t1 = new ThreadTest1(123);
    //        t1.setPriority(Thread.MAX_PRIORITY);
    //        t1.start();
    
            // 方式二 实现 Runnable 接口
    //        ThreadTest2 t2 = new ThreadTest2(666);
    //        new Thread(t2).start();
    
            // 加锁 实现线程同步
    //        ThreadTest3 t3_1 = new ThreadTest3();
    //        
    //        Thread t1 = new Thread(t3_1);
    //        t1.setName("ticket1");
    //        t1.start();
    //
    //        Thread t2 = new Thread(t3_1);
    //        t2.setName("ticket2");
    //        t2.start();
    
            // 同步方法 实现线程同步
    //        ThreadTest4 t4_1 = new ThreadTest4();
    //
    //        Thread t1 = new Thread(t4_1);
    //        t1.setName("ticket1");
    //        t1.start();
    //
    //        Thread t2 = new Thread(t4_1);
    //        t2.setName("ticket2");
    //        t2.start();
    
            // 线程安全 ReentrantLock 加锁 实现线程同步
    //        ThreadTest5 t5_1 = new ThreadTest5();
    //
    //        Thread t1 = new Thread(t5_1);
    //        t1.setName("ticket1");
    //        t1.start();
    //
    //        Thread t2 = new Thread(t5_1);
    //        t2.setName("ticket2");
    //        t2.start();
    
            // 方法三 实现 Callable 接口
    //        ThreadTest6 tt6 = new ThreadTest6();
    //        FutureTask<Integer> fTask = new FutureTask<Integer>(tt6);
    //        new Thread(fTask).start();
    //        try {
    //            // get()返回的是ThreadTest6的call()返回的sum
    //            Integer obj = fTask.get();
    //            System.out.println("sum:" + obj);
    //        } catch (InterruptedException e) {
    //            // TODO Auto-generated catch block
    //            e.printStackTrace();
    //        } catch (ExecutionException e) {
    //            // TODO Auto-generated catch block
    //            e.printStackTrace();
    //        }
            
            //方法四 使用线程池
            ExecutorService service = Executors.newFixedThreadPool(10);
          ThreadPoolExecutor s1 = (ThreadPoolExecutor)service;
          s1.setCorePoolSize(10);
          s1.setKeepAliveTime(1, TimeUnit.HOURS);
          s1.setMaximumPoolSize(30);
            s1.execute(new ThreadTest2());//适用于实现 Runnable 接口的类
            s1.submit(new ThreadTest6());//适用于实现 Callable 接口的类
            s1.shutdown();//关闭线程池
        }
    }
    
    /**
     * 1.创建一个继承Thread的子类 2.重写Thread的run(),将要执行的操作写在run()里面 3.创建子类的对象 4.调用子对象的start()
     */
    class ThreadTest1 extends Thread {
        public ThreadTest1() {
        }
    
        public ThreadTest1(int number) {
            super();
            this.number = number;
        }
    
        public int number;
    
        @Override
        public void run() {
            String tName = Thread.currentThread().getName();
            System.out.println(tName + "/" + number);
        }
    }
    
    class ThreadTest2 implements Runnable {
        public ThreadTest2() {
        }
    
        public ThreadTest2(int number) {
            super();
            this.number = number;
        }
    
        public int number;
    
        @Override
        public void run() {
            String tName = Thread.currentThread().getName();
            System.out.println(tName + "/" + number);
        }
    }
    
    /*
     * 线程安全 synchronized 加锁 实现线程同步
     */
    class ThreadTest3 implements Runnable {
        private static final Object objLock = new Object();
        public static int number = 100;
    
        @Override
        public void run() {
            while (true) {
                // 创建多个 ThreadTest3 对象时,使用 objLock/this.getClass()/ThreadTest3.class 当锁
                // 创建一个 ThreadTest3 对象,多个 Thread 使用该对象时,可以使用 this 当锁,尽量不要使用this锁
    //            synchronized (objLock) {
                synchronized (this.getClass()) {
    //            synchronized (ThreadTest3.class) {
    //            synchronized (this) {
                    if (number > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        String tName = Thread.currentThread().getName();
                        System.out.println("线程:" + tName + "售票:" + number);
                        number--;
                    } else {
                        break;
                    }
                }
            }
        }
    }
    
    /*
     * 线程安全 synchronized 同步方法 实现线程同步
     */
    class ThreadTest4 implements Runnable {
        public static int number = 100;
    
        @Override
        public void run() {
            while (true) {
                boolean res = show();
                if (!res) {
                    break;
                }
            }
        }
    
        // 使用 static synchronized修饰,同步监视器是 ThreadTest4.class,
        // 不加 static,同步监视器是 this,当new多个对象的时候会出错
        public static synchronized boolean show() {
            if (number > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String tName = Thread.currentThread().getName();
                System.out.println("线程:" + tName + "售票:" + number);
                number--;
            }
            return number > 0;
        }
    }
    
    /*
     * 线程安全 ReentrantLock 加锁 实现线程同步
     */
    class ThreadTest5 implements Runnable {
        public static int number = 100;
        private static ReentrantLock lock = new ReentrantLock();
    
        @Override
        public void run() {
            while (true) {
                boolean res = show();
                if (!res) {
                    break;
                }
            }
        }
    
        public static boolean show() {
            try {
                lock.lock();
                if (number > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String tName = Thread.currentThread().getName();
                    System.out.println("线程:" + tName + "售票:" + number);
                    number--;
                }
                return number > 0;
            } finally {
                lock.unlock();
            }
        }
    }
    /*
     * Callable
     * */
    class ThreadTest6 implements Callable<Integer> {
    
        @Override
        public Integer 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;
        }
    }
    
    // 单例模式
    class SingletonModel {
        // 私有构造函数,禁止外部new
        private SingletonModel() {
        }
    
        // 线程安全的饿汉式单例模式
    //    public static final SingletonModel instance1 = new SingletonModel();
    
        // 线程安全的懒汉式单例模式
        private static SingletonModel instance = null;
    
        public static SingletonModel getInstance() {
            if (instance == null) {
                synchronized (SingletonModel.class) {
                    if (instance == null) {
                        instance = new SingletonModel();
                    }
                }
            }
            return instance;
        }
    }

    join:阻塞当前线程,执行完join进来的线程后再继续当前线程。设置线程优先级:getPriority、setPriority,取值Thread.MAX_PRIORITY=10;使用ReentrantLock灵活加锁,实现线程同步
    线程通信:
    wait() 当前线程进入阻塞状态,并释放同步监视器。
    notify() 会唤醒被wait()的线程,如果有多个,则唤醒优先级高的线程。
    notifyAll 会唤醒所有被wait()的线程。
    这三个只能用在同步方法和同步代码块中,不能放在ReentrantLock中,并且这三个方法的调用者必须是同步代码块或同步方法中的同步监视器。
    例如:synchronized(this){...},则 this.notify(),synchronized(obj){...},则 obj.notify()
    线程池优点:提高响应速度,减少创建新线程的时间;降低资源消耗,重复使用线程池中的线程,不必每次都创建;便于线程管理(设置核心池大小,最大线程数,没有任务时线程最多保持多少时间后会终止)
    sleep()与wait(),
    相同点:一旦执行,都可以使当前线程阻塞。
    不同点:Thread类中声明sleep(),Object中声明wait();sleep可在任何场景使用,wait在同步代码块或同步方法中使用;如果两个方法都在同步代码块或同步方法中使用sleep不会释放锁,wait会释放锁。
    Thread.yield();线程让步,让cpu重新选择线程来执行,可能还会选择自己。
    yield、sleep、suspend都不会释放锁。

  • 相关阅读:
    silverlight中path对象使用总结
    推荐一款Silverlight数据列表控件AgDataGrid
    在silverlight中实现Marquee效果
    在silverlight中使用IsolateStore隔离存储(下)
    在silverlight中使用IsolateStore隔离存储(上)
    在Silverlight中使用DynamicMethod(动态方法)
    使用createObject(createObjectEx)创建silverlight对象
    在Silverlight中使用Json
    怎么这两天总能看到刺激我的好东西
    使silverlight适应IE窗口大小的方法
  • 原文地址:https://www.cnblogs.com/xsj1989/p/14601888.html
Copyright © 2011-2022 走看看