目录
创建线程的四种方式
① 继承Tread类,重写run方法。
② 实现runnable接口,重写run方法。
③ 使用FutureTask,重写callable方法,该方法是有返回值的。
④ 使用线程池。(本文章不做演示)
代码
package com.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class MyThread {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// lamdba 表达式
Thread t1 = new Thread(() -> System.out.println(Thread.currentThread().getId() + ": hello"));
// 静态内部类
Thread t2 = new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread().getId() + ": hello");
}
};
t1.start();
t2.start();
// 使用常规方法
MyRunnable runnable = new MyRunnable();
Thread t3 = new Thread(runnable);
// 静态内部类
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getId() +": hello");
}
});
// lamdba 表达式
Thread t5 = new Thread(() -> System.out.println(Thread.currentThread().getId() + ": hello"));
t3.start();
t4.start();
t5.start();
//创建FutureTask的对象
FutureTask<String> task =new FutureTask<String>(new MyCallable());
Thread t6 = new Thread(task);
t6.start();
//获取call()方法的返回值,即线程运行结束后的返回值
String result = task.get();
System.out.println(result);
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getId() + ": hello");
}
}
class MyCallable implements Callable {
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getId() + ": hello Callable");
return "hello Callable";
}
}
线程的生命周期
synchronized
synchronized关键字加在方法上,锁的是方法;加在普通方法上,锁对象可以是this;
加在静态方法上,锁对象可以是 类名.class;
这个地方先简单理解一下这是一个同步锁。原理还可以大做文章深入理解。
Lock
①Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问;
②Lock和synchronized有一点非常大的不同,采用synchronized不需要用户去手动释放锁,当synchronized方法或者synchronized代码块执行完之后,系统会自动让线程释放对锁的占用;而Lock则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
③ReentrantLock,意思是“可重入锁”,关于可重入锁的概念在下一节讲述。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。
代码
public class Test {
private ArrayList<Integer> arrayList =new ArrayList<Integer>();
private Lock lock =new ReentrantLock(); //注意这个地方
public static void main(String[] args) {
final Test test =new Test();
new Thread(){
public void run() {
test.insert(Thread.currentThread());
};
}.start();
new Thread(){
public void run() {
test.insert(Thread.currentThread());
};
}.start();
}
public void insert(Thread thread) {
lock.lock();
try {
System.out.println(thread.getName()+"得到了锁");
for(int i=0;i<5;i++) {
arrayList.add(i);
}
}catch (Exception e) {
// TODO: handle exception
}finally {
System.out.println(thread.getName()+"释放了锁");
lock.unlock();
}
}
}
多线程卖票问题
代码
package com.test;
public class ThreadSellingTickets {
public static void main(String[] args) {
SellingTickets st = new SellingTickets();
Thread t1 = new Thread(st, "张飞");
Thread t2 = new Thread(st, "刘备");
Thread t3 = new Thread(st, "关羽");
t1.start();
t2.start();
t3.start();
}
}
class SellingTickets implements Runnable {
private int tickets = 100;
@Override
public void run() {
while (true) {
// synchronized关键字加在方法上,锁的是方法;加在普通方法上,锁对象可以是this;
// 加在静态方法上,锁对象可以是 类名.class;
synchronized (this) {
if (tickets > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出第" + tickets + "张票");
tickets--;
}
}
}
}
}
生产者消费者模型
代码
待续。。
参考链接(本文仅限个人学习交流,支持原创,侵权必删)