// TheadDemo
public class ThreadDemo01 {
public static void main(String[] args) {
/**
* 多线程的第一种启动方式:
* 1. 定义一个类继承Thread
* 2. 重写run方法
* 3. 创建子类的对象, 并启动线程
*/
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.setName("thread1");
t2.setName("thread2");
// 开启线程
t1.start();
t2.start();
}
}
// MyThread
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + "Hello Thread!");
}
}
}
// Demo
public class ThreadDemo {
public static void main(String[] args) {
/**
* 多线程的第二种启动方式:
* 1. 定义一个类实现Runnable接口
* 2. 重写run方法
* 3. 创建自己的类的对象
* 4. 创建一个Thread类的对象, 并启动线程
*/
// 创建MyRunnable的对象
// 表示多线程要执行的任务
MyRunnable myRun = new MyRunnable();
// 创建线程对象
Thread t1 = new Thread(myRun);
Thread t2 = new Thread(myRun);
t1.setName("thread1");
t2.setName("thread2");
// 开启线程
t1.start();
t2.start();
}
}
// MyRunnable
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
// 获取当前线程的对象
Thread t = Thread.currentThread();
System.out.println(t.getName() + "Hello Runnable!");
}
}
}
// Demo
public class Demo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
/**
* 多线程的第三种实现方式
* 特点: 可以获取到多线程运行的结果
*
* 1. 创建一个类MyCallable实现Callable接口
* 2. 重写call (有返回值, 表示多线程运行的结果)
*
* 3. 创建MyCallable的对象 (表示多线程要执行的任务)
* 4. 创建FutureTask的对象 (管理多线程运行的结果)
* 5. 创建Thread类的对象, 并启动
*/
// 创建MyCallable的对象
Callable myC = new MyCallable();
// 创建FutureTask的对象
FutureTask<Integer> myF = new FutureTask<>(myC);
// 创建Thread类的对象
Thread t1 = new Thread(myF);
t1.start();
// 获取结果
Integer res = myF.get();
System.out.println(res);
}
}
// Impl
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 1~100求合
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
优点 | 缺点 | |
---|---|---|
继承Thread类 | 编程比较简单, 可以直接使用Thread类中的方法 | 可扩展性较差, 不能再继承其他的类 |
实现Runnable接口 | 扩展性强, 实现该接口的同时还可以继承其他的类 | 编程相对复杂, 不能直接使用Thread类中的方法 |
实现Callable接口 | 同实现Runnable接口 | 同实现Runnable接口 |
// Demo
public class demo {
public static void main(String[] args) throws InterruptedException {
/**
* String getName() 返回此线程的名称
* void setName(String name) 设置线程的名字(构造方法也可以设置名字)
* // 线程有默认的名字
* // 格式: Thread-x(x是序号, 从0开始)
*
* static Thread currentThread() 获取当前线程的对象
* // JVM虚拟机启动后, 会自动启动多条线程,
* // 其中有一条就叫做main线程, 它回去调用main方法
*
* static void sleep(long time) 让线程休眠指定的时间, 单位为毫秒
*/
// MyThread t1 = new MyThread("飞机");
// MyThread t2 = new MyThread("坦克");
//
// t1.start();
// t2.start();
Thread t = Thread.currentThread();
System.out.println(t.getName()); // main
System.out.println("111");
Thread.sleep(3000);
System.out.println("222");
}
}
// Thread
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* setPriority(int newPriority) 设置线程的优先级
* final int getPriority() 获取线程的优先级
*/
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr, "飞机");
Thread t2 = new Thread(mr, "坦克");
// 线程默认的优先级是5
System.out.println(t1.getPriority());
System.out.println(t2.getPriority());
System.out.println(Thread.currentThread().getPriority());
// 线程最大优先级是10, 最小是1
t2.setPriority(10);
t1.setPriority(1);
// 优先级指定的是线程抢占到cpu的概率
t1.start();
t2.start();
}
}
// runnable
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+"@"+i);
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* // 设置为守护线程
* final void setDaemon(boolean on)
* // 当其他的非守护线程执行完毕之后, 守护线程会陆续结束
*/
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.setName("女神");
t2.setName("备胎");
t2.setDaemon(true);
t1.start();
t2.start();
}
}
// MyThread1
public class MyThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(getName()+"@"+i);
}
}
}
// MyThread2
public class MyThread2 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* // 出让线程/礼让线程
* public static void yield
* 解释: 当前占据cpu的线程执行该方法后,
* 会让出cpu的执行权, 然后飞机和坦克会再次抢占cpu
* 效果: 可以让线程的执行比较均衡
*/
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.setName("飞机");
t2.setName("坦克");
t1.start();
t2.start();
}
}
// MyThread
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
// 出让当前cpu的执行权
Thread.yield();
}
}
}
// Demo
public class Demo {
public static void main(String[] args) throws InterruptedException {
/**
* // 插入线程/插队线程
* public final void join()
*/
MyThread t1 = new MyThread();
t1.setName("土豆");
t1.start();
// 表示把t这个线程, 插入到当前线程之前
// t: 土豆
// 当前线程: main线程
t1.join();
for (int i = 0; i < 10; i++) {
System.out.println("main线程"+i);
}
}
}
// MyThread
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName()+"@"+i);
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* 3个窗口模拟售卖100张票
*/
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
// MyThread
public class MyThread extends Thread{
// 表示这个类所有的对象, 都共享ticket
static int ticket = 0;
// 锁对象, 一定要是唯一的
// static Object obj = new Object();
@Override
public void run() {
while(true)
{
// 同步代码块
synchronized (MyThread.class){
if(ticket >= 100){
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
++ticket;
System.out.println(getName()+"正在卖第"+ticket+"张票");
}
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* 3个窗口模拟售卖100张票
*/
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr);
Thread t2 = new Thread(mr);
Thread t3 = new Thread(mr);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
// MyRunnable
public class MyRunnable implements Runnable{
// 只有一个Runnable对象, 不用static
int ticket = 0;
@Override
public void run() {
while(true)
{
if (method()) break;
}
}
private synchronized boolean method() {
if(ticket >= 1000){
return true;
}
Thread t = Thread.currentThread();
++ticket;
System.out.println(t.getName()+"正在卖第"+ticket+"张票");
return false;
}
}
this
, 静态方法是当前类的字节码文件对象
StringBuilder
是线程不安全的, StringBuffer
是线程安全的(它的方法是有添加synchronized
关键字)// Demo
public class Demo {
public static void main(String[] args) {
/**
* 3个窗口模拟售卖100张票
*/
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
// MyThread
public class MyThread extends Thread{
// 表示这个类所有的对象, 都共享ticket
static int ticket = 0;
static Lock lock = new ReentrantLock();
@Override
public void run() {
while(true)
{
lock.lock();
try {
if(ticket >= 1000){
break;
}
Thread.sleep(1);
++ticket;
System.out.println(getName()+"正在卖第"+ticket+"张票");
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
}
}
}
break
循环之后, 直接跳出循环而没有解锁, 导致程序不会停止// Demo
public class Demo {
public static void main(String[] args) {
/**
* 死锁
*/
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.setName("线程A");
t2.setName("线程B");
t1.start();
t2.start();
}
}
// MyThread
public class MyThread extends Thread{
static Object objA = new Object();
static Object objB = new Object();
@Override
public void run() {
while(true)
{
if(getName().equals("线程A")){
synchronized (objA){
System.out.println("线程A拿到了A锁, 准备去拿B锁");
synchronized (objB){
System.out.println("线程A拿到了B锁, 顺利执行完了一轮");
}
}
}else if(getName().equals("线程B")){
synchronized (objB){
System.out.println("线程B拿到了B锁, 准备去拿A锁");
synchronized (objA){
System.out.println("线程B拿到了A锁, 顺利执行完了一轮");
}
}
}
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* 实现生产者和消费者(等待唤醒机制)
* 实现线程轮流交替执行
*/
Cook c = new Cook();
Foodie f = new Foodie();
c.start();
f.start();
}
}
// Desk
public class Desk {
/**
* 控制生产者和消费者的执行
*/
// 是否有面条 0: 没有面条, 1: 有面条
public static int foodflag = 0;
// 总个数
public static int count = 10;
// 锁对象
public static Object lock = new Object();
}
// Cook
public class Cook extends Thread {
@Override
public void run() {
while(true)
{
synchronized (Desk.lock){
if(Desk.count == 0){
break;
}else{
// 判断桌子上是否有食物
if(Desk.foodflag == 1){
// 如果有, 就等待
System.out.println("还有, 不做");
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
// 如果没有, 就制作食物
System.out.println("厨师做了一碗面条");
// 修改桌子上的食物状态
Desk.foodflag = 1;
// 叫醒等待的消费者开吃
Desk.lock.notifyAll();
}
}
}
}
}
}
// Foodie
public class Foodie extends Thread{
@Override
public void run() {
while(true)
{
synchronized (Desk.lock){
if(Desk.count == 0){
break;
}else{
// 先判断桌子上是否有面条
if(Desk.foodflag == 0){
// 如果没有, 就等待
System.out.println("没得吃");
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}else{
// 把吃的总数-1
Desk.count -= 1;
// 如果有, 就开吃
System.out.println("吃货正在吃面条, 还能吃"+Desk.count+"碗");
// 吃完之后, 唤醒厨师继续做
Desk.lock.notifyAll();
// 修改桌子的状态
Desk.foodflag = 0;
}
}
}
}
}
}
// Demo
public class Demo {
public static void main(String[] args) {
/**
* 阻塞队列实现生产者和消费者(等待唤醒机制)
*/
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
Cook c = new Cook(queue);
Foodie f = new Foodie(queue);
c.start();
f.start();
}
}
// Cook
public class Cook extends Thread {
ArrayBlockingQueue<String> queue;
public Cook(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while(true)
{
try {
queue.put("面条");
System.out.println("厨师放了一碗面条");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
// Foodie
public class Foodie extends Thread{
ArrayBlockingQueue<String> queue;
public Foodie(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while(true)
{
try {
String take = queue.take();
System.out.println("吃货拿了一碗"+take);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
黑马程序员. 阿玮Java零基础
https://gitee.com/yu-ba-ba-ba/awJava