线程创建
创建一个线程主要有以下几种方法:
-
Thread:继承Thread类
-
Runnable:实现Runnable接口
-
Callable:实现Callable接口
继承Thread类创建线程
是将一个类声明为Thread的子类,这个子类应该重写Thread类的run方法,然后实例化这个子类对象并调用start方法。Thread类本质上是实现了Runnable接口的一个实例。
public class TestThread extends Thread{
@Override
public void run() {
int i = 0;
while(i<=100){
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("副线程正在输出..." + i++ );
}
}
public static void main(String[] args) {
TestThread testThread = new TestThread();
testThread.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程也在输出..." + i);
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
实现Runnable接口
如果一个类已经继承了其他类,那么可以通过实现Runnable接口,重写run方法,然后以实现Runnable接口的对象作为参数创建Thread类的对象,调用Thread对象的start方法,new Thread(runnable).start() 。推荐使用这个方法,可以避免单继承的弊端。
黄牛抢票的例子
// 此处并发,多个线程公用一个变量,不安全
public class TestThread4 implements Runnable {
private int ticket = 10;
@Override
public void run() {
while(ticket > 0){
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---> 拿到了第" + ticket-- + "票!");
}
}
public static void main(String[] args) {
TestThread4 ticket = new TestThread4();
new Thread(ticket, "小明").start();
new Thread(ticket, "老师").start();
new Thread(ticket, "黄牛党").start();
}
}
龟兔赛跑的例子:
public class Race implements Runnable {
private String winner;
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
try{
if(Thread.currentThread().getName() == "乌龟"){
Thread.sleep(80); // 乌龟每走一步休息80毫秒
}
else if (Thread.currentThread().getName() == "兔子" && i%10 ==0){
Thread.sleep(1000); // 兔子每走十步休息1秒
}
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->跑了" + i + "步!");
boolean flag = gameOver(i);
if(flag){
break;
}
}
}
private boolean gameOver(int step){
if(winner != null){
return true;
}
if(step >= 100){
winner = Thread.currentThread().getName();
System.out.println("Winner is " + winner);
return true;
}else{
return false;
}
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race, "兔子").start();
new Thread(race, "乌龟").start();
}
}
实现Callable接口
- 实现Callable接口,需要返回值类型
- 重写call方法,需要抛出异常
- 创建目标对象
- 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);
- 提交执行:Future result1 = ser.submit(t1);
- 获取结果:boolean r1= result1.get();
- 关闭服务: ser.shutdownNow();
public class TestCallable implements Callable<Boolean> {
private int ticket = 10;
@Override
public Boolean call() throws Exception {
while (ticket > 0){
try{
Thread.sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿到了第" + ticket-- +"张票!");
}
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
TestCallable testCallable = new TestCallable();
// 创建执行服务:
ExecutorService ser = Executors.newFixedThreadPool(3);
// 提交执行:
Future<Boolean> result1 = ser.submit(testCallable);
Future<Boolean> result2 = ser.submit(testCallable);
Future<Boolean> result3 = ser.submit(testCallable);
// 获取结果:
boolean r1 = result1.get();
boolean r2 = result2.get();
boolean r3 = result3.get();
// 关闭服务:
ser.shutdownNow();
}
}