// synchronized ['sɪŋkrənaɪzd] 同步的
// 可以保证块中的代码是同步执行的
// 只有一个线程执行完块中的代码后,另外一个线程才能执行块中的代码
// 可以称为同步锁
@Override public void run() { // synchronized ['sɪŋkrənaɪzd] 同步的 // 可以保证块中的代码是同步执行的 // 只有一个线程执行完块中的代码后,另外一个线程才能执行块中的代码 // 可以称为同步锁 while (true) { synchronized (this) { // 加锁,只有当前线程才可以使用 if (ticket > 0) { System.out.println("TaskRunable 卖了一张票...."); ticket--; } else { break; } }// 解锁 } }
@Override public void run() { while (true) { // 返回值决定是否跳出循环 boolean flag = sellTicket(); if (flag) { break; } } } // synchronized 修饰的方法为同步方法,多线程间依次执行 private synchronized boolean sellTicket() { boolean result = false; if (ticket > 0) { try { // 让当前线程休眠一段时间,暂停一段时间,线程进入阻塞状态 // 唤醒线程进入就绪状态 // 单位是毫秒 Thread.sleep(500); } catch (InterruptedException e) { // 打断休眠会产生异常 e.printStackTrace(); } // Thread.currentThread() 获得当前代码在哪个线程执行 // getName() 获得当前线程的名字 System.out.println(Thread.currentThread().getName() + " 卖了一张票,剩余:" + (--ticket) + " 张"); }else { result = true; } return result; }
2 线程池的使用
// 使用线程池可以避免创建大量的线程,实现线程的重用,提高效率
// ExecutorService 线程池
// Executors 线程池创建对象
// newCachedThreadPool:容量无限的线程池
// 有可重用的就重用,没有就创建新的线程
ExecutorService executorService1 = Executors.newCachedThreadPool(); for (int i = 0; i < 30; i++) { if (i % 5 == 0) { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } TaskThread taskThread = new TaskThread(); // 把需要再分线程执行的任务加入线程中 executorService1.execute(taskThread); } // 线程池使用完要关闭,清理所有资源。 executorService1.shutdown();
// newFixedThreadPool:指定容量的线程池
// 有可重用的就重用,没有就等待别人使用完毕再使用
ExecutorService executorService2 = Executors.newFixedThreadPool(10); for (int i = 0; i < 30; i++) { TaskThread taskThread = new TaskThread(); executorService2.execute(taskThread); } executorService2.shutdown();
// newSingleThreadExecutor:容量为 1 的线程池
// 排队使用
ExecutorService executorService3 = Executors.newSingleThreadExecutor(); for (int i = 0; i < 30; i++) { TaskThread taskThread = new TaskThread(); executorService3.execute(taskThread); } executorService3.shutdown();
// 实际工作中,对于大量的并发操作都会使用线程池进行管理,节省资源,提高效率 通过以上得出三种创建线程和使用的方法基本一样 可以根据实际情况来使用