// 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();
// 实际工作中,对于大量的并发操作都会使用线程池进行管理,节省资源,提高效率 通过以上得出三种创建线程和使用的方法基本一样 可以根据实际情况来使用