概述


线程创建

继承Thread

// 继承Thread类,重写run方法,调用start开启线程
public class TestThread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("this is run method");
}
}
public static void main(String[] args) {
TestThread1 testThread1 = new TestThread1();
testThread1.start();
//testThread1.run(); 串行执行
for (int i = 0; i < 500; i++) {
System.out.println("main");
}
}
}
注意调用start()和 run()的区别,start才是多线程,run方法依旧是串行执行,main是主线程
多线程下载图片案例


实现Runnable接口
Thread实际上也是实现的Runnable接口

public class CreateByRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("run");
}
}
public static void main(String[] args) {
// 注意这个线程创建和继承Thread的区别,实际上是把run方法的实现放到接口中做,
// 然后将接口实现类对象当做参数,传给thread构造方法。
CreateByRunnable createByRunnable = new CreateByRunnable();
Thread thread = new Thread(createByRunnable);
thread.start();
for (int i = 0; i < 500; i++) {
System.out.println("main");
}
}
}

实现Callable接口



静态代理


Lambda表达式



线程状态


sleep

倒计时
public class LastTime {
public static int time = 10;
public static void run() {
while (time >= 0){
System.out.println(time);
try {
Thread.sleep(1000); // sleep one second
} catch (InterruptedException e) {
e.printStackTrace();
}
time --;
}
}
public static void main(String[] args) {
run();
}
}
线程礼让yield
礼让未必成功,是放弃cpu直接进入就绪队列,不会释放其他资源

插队join

线程优先级,优先级低的未必后执行,看概率。默认是5公平竞争

守护线程


线程同步

Lock锁


import java.util.concurrent.locks.ReentrantLock;
public class TestLock implements Runnable {
private int ticket = 10;
@Override
public void run() {
//可重入锁
ReentrantLock lock = new ReentrantLock();
while (true) {
try {
lock.lock();
if (ticket > 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticket--);
}else break;
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
TestLock testLock = new TestLock();
new Thread(testLock).start();
new Thread(testLock).start();
new Thread(testLock).start();
}
}
可重入锁和不可重入锁
当A方法获取lock锁去锁住一段需要做原子性操作的B方法时,如果这段B方法又需要锁去做原子性操作,那么A方法就必定要与B方法出现死锁。这种会出现问题的重入一把锁的情况,叫不可重入锁。

线程通信

生产者和消费者模型,管程法,就是一个缓冲区
public class TestPC {
public static void main(String[] args) {
Container container = new Container();
new Thread(new Producer(container)).start();
new Thread(new Consumer(container)).start();
}
}
class Producer implements Runnable {
private Container container;
Producer(Container container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.put(new Chiken(i));
System.out.println("create:"+i);
}
}
}
class Consumer implements Runnable {
private Container container;
Consumer(Container container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("consum"+container.pop().getId());
// container.pop();
}
}
}
class Container{
private Chiken[] container = new Chiken[10];
private int count = 0;
Container() {
}
public synchronized void put(Chiken chiken){
if(count >= 10){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
container[count++] = chiken;
this.notifyAll();
}
}
public synchronized Chiken pop(){
if(count <= 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return container[--count];
}
}
class Chiken{
private int id;
public int getId() {
return id;
}
public Chiken(int id) {
this.id = id;
}
public void setId(int id) {
this.id = id;
}
}
线程池


4万+

被折叠的 条评论
为什么被折叠?



