定時任務
- Rx
public class RxUtils {
static public Observable<Integer> countDown(int time) {
if (time < 0) time = 0;
final int countTime = time;
return Observable.interval(0, 1, TimeUnit.SECONDS)
.map(new Func1<Long, Integer>() {
@Override
public Integer call(Long increaseTime) {
return countTime - increaseTime.intValue();
}
})
.take(countTime + 1);
//
// Observable.timer(time,TimeUnit.SECONDS).filter(new Func1<Long, Boolean>() {
// @Override
// public Boolean call(Long aLong) {
// return null;
// }
// })
}
}
-
Timer
Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { LogUtil.v("java", "任務開始"); } }; timer.schedule(timerTask, 1000); timer.schedule(timerTask, 1000); ps:timer.cancel;
-
Handler
Handler handler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { LogUtil.v("java", "定時任務開啟"); } }; handler.postDelayed(runnable, 1000); //handler.removeCallbacksAndMessages(null);
-
AlarmManager
am = (AlarmManager) this.getSystemService(ALARM_SERVICE); Intent i = new Intent(this, UpdateReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, i, 0); //am.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, pendingIntent); am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000, pendingIntent);
鎖機制
- 概念
- 原子性:只有一個線程能夠執(zhí)行這個代碼
- 可見性: 保證前后修改的資源一致
- 分類
synchronized
-
ReentrantLock:可重入的意義在于持有鎖的線程可以繼續(xù)持有硼婿,并且要釋放對等的次數(shù)后才真正釋放該鎖
class Outputter1 { private Lock lock = new ReentrantLock();// 鎖對象 public void output(String name) { lock.lock(); // 得到鎖 try { //do something } finally { lock.unlock();// 釋放鎖 } } }
-
ReadWriteLock:可以同時讀取,限制寫入
class Data { private int data;// 共享數(shù)據(jù) private ReadWriteLock rwl = new ReentrantReadWriteLock(); public void set(int data) { rwl.writeLock().lock();// 取到寫鎖 try { System.out.println(Thread.currentThread().getName() + "準備寫入數(shù)據(jù)"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.data = data; System.out.println(Thread.currentThread().getName() + "寫入" + this.data); } finally { rwl.writeLock().unlock();// 釋放寫鎖 } } public void get() { rwl.readLock().lock();// 取到讀鎖 try { System.out.println(Thread.currentThread().getName() + "準備讀取數(shù)據(jù)"); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "讀取" + this.data); } finally { rwl.readLock().unlock();// 釋放讀鎖 } } }
-
和Condition的結(jié)合
class BoundedBuffer { final Lock lock = new ReentrantLock();//鎖對象 final Condition notFull = lock.newCondition();//寫線程條件 final Condition notEmpty = lock.newCondition();//讀線程條件 final Object[] items = new Object[100];//緩存隊列 int putptr/*寫索引*/, takeptr/*讀索引*/, count/*隊列中存在的數(shù)據(jù)個數(shù)*/; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length)//如果隊列滿了 notFull.await();//阻塞寫線程 items[putptr] = x;//賦值 if (++putptr == items.length) putptr = 0;//如果寫索引寫到隊列的最后一個位置了犁苏,那么置為0 ++count;//個數(shù)++ notEmpty.signal();//喚醒讀線程 } finally { lock.unlock(); } } public Object take() throws InterruptedException { lock.lock(); try { while (count == 0)//如果隊列為空 notEmpty.await();//阻塞讀線程 Object x = items[takeptr];//取值 if (++takeptr == items.length) takeptr = 0;//如果讀索引讀到隊列的最后一個位置了锐峭,那么置為0 --count;//個數(shù)-- notFull.signal();//喚醒寫線程 return x; } finally { lock.unlock(); } } }
多線程總結(jié)
-
管理類
-
基本
ExecutorService e = Executors.newCachedThreadPool(); ExecutorService e = Executors.newSingleThreadExecutor(); ExecutorService e = Executors.newFixedThreadPool(3); // 第一種是可變大小線程池,按照任務數(shù)來分配線程贤惯, // 第二種是單線程池老速,相當于FixedThreadPool(1) // 第三種是固定大小線程池啊研。 // 然后運行 e.execute(new MyRunnableImpl());
-
定時任務線程
ScheduledExecutorService threadPools = Executors.newScheduledThreadPool(2); for(int i = 0; i < 2;i++){ threadPools.schedule(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "定時器執(zhí)行"); } }, 2, TimeUnit.SECONDS); } threadPools.shutdown(); //scheduleAtFixedRate 這個方法是不管你有沒有執(zhí)行完裙戏,反正我每隔4秒來執(zhí)行一次乘凸,以相同的頻率來執(zhí)行 //scheduleWithFixedDelay 這個是等你方法執(zhí)行完后,我再隔4秒來執(zhí)行累榜,也就是相對延遲后营勤,以固定的頻率去執(zhí)行
-
Semaphore就是一個信號量,它的作用是限制某段代碼塊的并發(fā)數(shù)
-
FutureTask類實現(xiàn)了RunnableFuture接口信柿,我們看一下RunnableFuture接口的實現(xiàn)冀偶,RunnableFuture繼承了Runnable接口和Future接口醒第,而FutureTask實現(xiàn)RunnableFuture接口渔嚷。所以它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值稠曼。
public class Test { public static void main(String[] args) { //第一種方式 ExecutorService executor = Executors.newCachedThreadPool(); Task task = new Task(); FutureTask<Integer> futureTask = new FutureTask<Integer>(task); executor.submit(futureTask); executor.shutdown(); //第二種方式形病,注意這種方式和第一種方式效果是類似的,只不過一個使用的是ExecutorService霞幅,一個使用的是Thread /*Task task = new Task(); FutureTask<Integer> futureTask = new FutureTask<Integer>(task); Thread thread = new Thread(futureTask); thread.start();*/ try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("主線程在執(zhí)行任務"); try { System.out.println("task運行結(jié)果"+futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("所有任務執(zhí)行完畢"); } } class Task implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("子線程在進行計算"); Thread.sleep(3000); int sum = 0; for(int i=0;i<100;i++) sum += i; return sum; } }
參考
- http://blog.csdn.net/dxpqxb/article/details/8659292
- http://blog.csdn.net/vking_wang/article/details/9952063
- http://www.reibang.com/p/40d4c7aebd66 多線程
- http://mybar.iteye.com/blog/1829883 線程池
- http://www.cnblogs.com/dolphin0520/p/3949310.html Future
- http://blog.csdn.net/yaojiank/article/details/8888186