线程
什么是线程:
什么是多线程:
学习目的:
多线程的创建
方式一:继承Thread类
public class MyThread{
public static void main(String[] args) {
Thread thread01 = new Thread01();
thread01.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程执行输出:"+i);
}
}
}
class Thread01 extends Thread{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程执行输出:"+i);
}
}
}
注意:
如果用thread01.run()而不用thread01.start(),那么将还是单线程执行。
主线程任务不要放在子线程之前,否则还是单线程的情形。
方式二:实现Runnable
方式二相对于方式一来说线程类可以继承别的类。
public class MyThread{
public static void main(String[] args) {
Runnable r = new MyRunnable();
// r为任务对象,要交给一个线程对象去处理。
Thread thread = new Thread(r);
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程输出:"+i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程输出:"+i);
}
}
}
public class MyThread{
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程输出:"+i);
}
}
};
// r为任务对象,要交给一个线程对象去处理。
Thread thread = new Thread(r);
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程输出:"+i);
}
}
}
方式三:jdk5.0新增,实现Callable接口
public class ThreadDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建callable任务对象
Callable<String> c = new MyCallable(100);
// 把callable任务对象交给FutureTask对象:是Runnable对象(实现了Runnable接口),可以交给Thread
// FutureTask对象可以使用get方法得到线程返回的结果
FutureTask<String> f = new FutureTask<>(c);
Thread t = new Thread();
t.start();
// 如果f任务没有执行完毕,则f.get()会等待,线程跑完才提取结果
System.out.println(f.get());
}
}
class MyCallable implements Callable<String>{
private int n;
public MyCallable(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum = sum + i;
}
return "子线程的结果为:"+sum;
}
}
三种方式的对比
Thread的常用方法
自定义线程名字1:
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new MyThread();
t1.setName("1号");
t1.start();
Thread t2 = new MyThread();
t2.setName("2号");
t2.start();
// 哪个线程执行它,他就返回哪个线程(当前线程对象)。
Thread ct = Thread.currentThread();
// 主线程调用它,拿到主线程的名字(main)。
String s = ct.getName();
for (int i = 0; i < 4; i++) {
System.out.println(s+"线程输出"+i);
}
}
}
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+"线程输出"+i);
}
}
}
自定义线程名字2:
public class ThreadDemo {
public static void main(String[] args) {
Thread t1 = new MyThread("1号");
t1.start();
Thread t2 = new MyThread("2号");
t2.start();
// 哪个线程执行它,他就返回哪个线程(当前线程对象)。
Thread ct = Thread.currentThread();
// 主线程调用它,拿到主线程的名字(main)。
String s = ct.getName();
for (int i = 0; i < 4; i++) {
System.out.println(s+"线程输出"+i);
}
}
}
class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+"线程输出"+i);
}
}
}
线程的休眠方法:
线程安全
public class MyThread {
public static void main(String[] args) {
Account account = new Account("houyiming",100000);
new DrawThread(account,"小明").start();
new DrawThread(account,"小红").start();
}
}
public class DrawThread extends Thread {
private Account acc;
public DrawThread(Account acc,String name){
super(name);
this.acc = acc;
}
@Override
public void run() {
acc.drawMoney(100000);
}
}
public class Account {
private String CardId;
private int money;
public Account(String cardId, int money) {
CardId = cardId;
this.money = money;
}
public Account() {
}
public String getCardId() {
return CardId;
}
public void setCardId(String cardId) {
CardId = cardId;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
public void drawMoney(int money){
String s = Thread.currentThread().getName();
if (this.money >= money){
System.out.println(s+"取钱,吐出:"+money);
this.money -= money;
System.out.println(s+"取钱后剩余:"+this.money);
}else{
System.out.println(s+":余额不足 ");
}
}
}
线程同步
同步代码块
synchronized ("houyiming") { // 锁对象任意,但是要唯一。
if (this.money >= money){
System.out.println(s+"取钱,吐出:"+money);
this.money -= money;
System.out.println(s+"取钱后剩余:"+this.money);
}else{
System.out.println(s+":余额不足 ");
}
}
synchronized (this) {
if (this.money >= money){
System.out.println(s+"取钱,吐出:"+money);
this.money -= money;
System.out.println(s+"取钱后剩余:"+this.money);
}else{
System.out.println(s+":余额不足 ");
}
}
同步方法
public synchronized void drawMoney(int money){
String s = Thread.currentThread().getName();
if (this.money >= money){
System.out.println(s+"取钱,吐出:"+money);
this.money -= money;
System.out.println(s+"取钱后剩余:"+this.money);
}else{
System.out.println(s+":余额不足 ");
}
}
Lock锁
private final Lock lock = new ReentrantLock();
public void drawMoney(int money){
String s = Thread.currentThread().getName();
lock.lock();
try {
if (this.money >= money){
System.out.println(s+"取钱,吐出:"+money);
this.money -= money;
System.out.println(s+"取钱后剩余:"+this.money);
}else{
System.out.println(s+":余额不足 ");
}
} finally {
lock.unlock();
}
}
线程通信
线程池[重点]
线程池实现的API、参数说明
方式一:
线程池实现Runnable接口
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建线程池对象
ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
// 把任务交给线程池处理
Runnable r = new MyRunnable();
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
pool.execute(r);
// 关闭线程池,即使任务没有完成,会丢失任务
pool.shutdownNow();
// 等所有任务完成之后关闭
pool.shutdown();
}
}
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+": hello world : "+i);
try {
Thread.sleep(100000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
线程池实现Callable任务
public class ThreadPoolDemo2 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建线程池对象
ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
// 把任务交给线程池处理
Future<String> f1 = pool.submit(new MyCallable(100));
Future<String> f2 = pool.submit(new MyCallable(200));
Future<String> f3 = pool.submit(new MyCallable(300));
Future<String> f4 = pool.submit(new MyCallable(400));
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
}
}
public class MyCallable implements Callable<String> {
private int n;
public MyCallable(int n){
this.n = n;
}
public MyCallable(){
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
return Thread.currentThread().getName()+"执行"+1+"到"+n+"的结果为:"+sum;
}
}
Executors工具类实现线程池
ExecutorService pool = Executors.newFixedThreadPool(3);
定时器
Timer定时器
public class TimerDemo1 {
public static void main(String[] args) {
Timer timer = new Timer(); // 定时器本身就是一个线程
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行一次");
}
},3000,2000);
}
}
ScheduledExecutorService定时器
public class TimerDemo1 {
public static void main(String[] args) {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"11执行输出");
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},0,2, TimeUnit.SECONDS);
pool.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"22执行输出");
}
},0,2, TimeUnit.SECONDS);
}
}
并发并行、生命周期