编程学习笔记

<<java编程思想>>笔记:并发2

2018-09-29  本文已影响12人  烛火的咆哮
  1. java中的原子操作类
    原子操作是指程序编译后,对应于一条cpu操作指令,即原子操作时最小的不可再分指令集,编程中的原子操作是线程安全的,不需要使用进行线程同步和加锁机制来确保原子操作的线程同步
public class AtomicIntergerTest implements Runnable { // 创建一个值为0的Integer类型原子类
    private AtomicInteger i = new AtomicInteger(0);

    public int getValue() { // 获取Integer类型原子类的值
        return i.get();
    }

    private void evenIncrement() { // 值增加2
        i.addAndGet(2);
    }

    public void run() {
        while (true) {
            evenIncrement();
        }
    }

    //
    public static void main(String[] args) {
        // 创建一个定时任务,5秒钟终止运行
        new Timer().schedule(new TimerTask() {
            public void run() {
                System.err.println("abort");
                System.exit(0);
            }
        }, 5000);
        ExecutorService exec = Executors.newCachedThreadPool();
        AtomicIntergerTest at = new AtomicIntergerTest();
        exec.execute(at);
        while (true) {
            int val = at.getValue();
            // 奇数
            if (val % 2 != 0) {
                System.out.println(val);
                System.exit(0);
            }
        }
    }
}
  1. 线程本地存储
public class UniqueThreadGenerator {
    private static final AtomicInteger uniqueId = new AtomicInteger(0);
    // 创建一个线程局部变量
    private static final ThreadLocal<Integer> uniqueNum = new ThreadLocal<Integer>() {
        // 覆盖线程局部变量的initialvalue方法,为线程局部变量初始化赋值
        protected Integer initialValue() {
            return uniqueId.getAndIncrement();
        }
    };

    public static int getCurrentThreadId() {
        // 获取线程局部变量的当前线程副本中的值
        return uniqueId.get();
    }
}

线程局部变量ThreadLocal类中有下面四个方法:

  1. 线程的yield,sleep和wait的区别
    a. yield:
  1. 线程间的通信

b. await(),signal(),signalAll()进行线程通信:

  1. 使用ScheduledThreadPoolExeecutor实现定时任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

 class DemoSchedule  {
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    // 创建并在给定延迟后时间启动一词性操作
    public void schedule(Runnable event, long delay) {
        scheduler.schedule(event, delay, TimeUnit.SECONDS);
    }

    // 创建并在给定延迟时间后,每个给定时间周期性执行的操作
    public void repeat(Runnable event, long initiadelay, long period) {
        scheduler.scheduleAtFixedRate(event, initiadelay, period, TimeUnit.SECONDS);
    }
}

class OnetimeSchedule implements Runnable {
    public void run() {
        System.out.println("one time schedule task:");
    }
}

class RepeatSchedule implements Runnable {
    public void run() {
        System.out.println("repeat schedule task: ");
    }
}
/**
 * 定时任务示例 
 * @author zhdpx
 *
 */
public class TestSchedule{
    public static void main(String[] args) {
        DemoSchedule  scheduler = new DemoSchedule ();
        scheduler.schedule(new OnetimeSchedule(), 10);
        scheduler.repeat(new RepeatSchedule(), 5,5);
    }
}
  1. 信号量Semaphore
public class Pool<T> {
    // 限制的线程数目
    private int size;
    // 存放资源集合
    private List<T> items = new ArrayList<T>();
    // 标记资源是否被使用
    private volatile boolean[] checkedOut;
    private Semaphore available;

    public Pool(Class<T> classObject, int size) {
        this.size = size;
        checkedOut = new boolean[size];
        // 创建信号量对象
        available = new Semaphore(size, true);
        for (int i = 0; i < size; ++i) {
            try {
                // 加载资源对象那个并存放到集合中
                items.add(classObject.newInstance());
            } catch (Exception e) {
                throw new RuntimeException(e);
                // TODO: handle exception
            }
        }
    }

    // 访问资源
    public T checkout() throws InterruptedException {
        // 获取许可
        available.acquire();
        return getItem();
    }

    // 释放资源
    public void checkIn(T x) {
        if (releaseItem(x))
            // 释放一个资源许可,将其返回给信号量
            available.release();
    }

    // 获取资源
    private synchronized T getItem() {
        for (int i = 0; i < size; i++) {
            // 资源没有被使用
            if (!checkedOut[i]) {
                // 标记资源被使用
                checkedOut[i] = true;
                return items.get(i);
            }
        }
        return null;
    }

    private synchronized boolean releaseItem(T item) {
        int index = items.indexOf(item);
        // 资源不在资源集合中
        if (index == -1)
            return false;
        // 资源正在被使用
        if (checkedOut[index]) {
            // 将资源标记为不再使用
            checkedOut[index] = false;
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        
    }
}
  1. Exchanger线程同步交换器
public class TestExchanger {
    Cup emptyCup = new Cup(0);
    Cup fullCup = new Cup(100);
    Exchanger<Cup> exchanger = new Exchanger<Cup>();

    // 服务员类
    class Waiter implements Runnable {
        private int addSpeed = 1;

        public Waiter(int addspeed) {
            this.addSpeed = addspeed;
        }

        public void run() {
            while (emptyCup != null) {
                try {
                    // 如果被子已满,则与顾客交换,服务员获得空杯
                    if (emptyCup.isFull()) {
                        emptyCup = exchanger.exchange(emptyCup);
                        System.out.println("waiter : " + emptyCup.getCapacity());
                    } else {
                        emptyCup.addWaterToCup(addSpeed);
                        System.out.println(
                                "waiter add " + addSpeed + " and current capacity is: " + emptyCup.getCapacity());
                        TimeUnit.SECONDS.sleep(new Random().nextInt(10));
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    // TODO: handle exception
                }
            }
        }
    }

    // 顾客类
    class Customer implements Runnable {
        int drinkSpeed = 1;

        public Customer(int drinkSpeed) {
            this.drinkSpeed = drinkSpeed;
        }

        public void run() {
            while (fullCup != null) {
                try {
                    // 如果杯子已空,则与服务员进行交换,顾客获得装满水的杯子
                    if (fullCup.isEmpty()) {
                        fullCup = exchanger.exchange(fullCup);
                        System.out.println("Customer: " + fullCup.getCapacity());
                    } else {
                        fullCup.drinkWaterFromCup(drinkSpeed);
                        System.out.println(
                                "Customer drink " + drinkSpeed + " and current capacity is : " + fullCup.getCapacity());
                        TimeUnit.SECONDS.sleep(new Random().nextInt(10));
                    }
                } catch (InterruptedException e) {

                    e.printStackTrace();// TODO: handle exception
                }
            }
        }
    }
    public static void main(String[] args) {
        TestExchanger test = new TestExchanger();
        new Thread(test.new Waiter(3)).start();
        new Thread(test.new Customer(6)).start();
    }
}

class Cup {
    private int capacity = 0;

    public Cup(int capacity) {
        this.capacity = capacity;
    }

    public int getCapacity() {
        return capacity;
    }

    public void addWaterToCup(int i) {
        capacity += i;
        capacity = capacity > 100 ? 100 : capacity;
    }

    public void drinkWaterFromCup(int i) {
        capacity += i;
        capacity = capacity < 0 ? 0 : capacity;
    }

    public boolean isFull() {
        return capacity == 100 ? true : false;
    }

    public boolean isEmpty() {
        return capacity == 0 ? true : false;
    }
}

代码目测记事本手撸,小错误很多,都修正了下
原帖传送门

上一篇 下一篇

猜你喜欢

热点阅读