多线程使用的第一种方法:
public class TestThread1 extends Thread {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("我在看代码---------");
}
}
public static void main(String[] args) {
//main线程,主线程
//创建一个线程对象
TestThread1 testThread1 = new TestThread1();
//调用start方法开启线程
testThread1.start();
for (int i = 0; i < 2000; i++) {
System.out.println("我在学习多线程-----");
}
}
}
多线程使用的第二种方法:
//创建线程方式:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类调用star方法。
public class TestThread3 implements Runnable{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 200; i++) {
System.out.println("我在看代码-------");
}
}
public static void main(String[] args) {
//穿件runnable接口的实现独享
TestThread3 testThread3 = new TestThread3();
//创建线程对象,通过线程对象来开启我们的线程,代理模式
/* Thread thread = new Thread(testThread3);
thread.start();*/
new Thread(testThread3).start();
//开启线程
for (int i = 0; i < 1000; i++) {
System.out.println("我在学习多线程---------");
}
}
}
多线程下载照片,表明多个进程之间同时进行
public class TestThread2 extends Thread{
private String url;
private String name;
public TestThread2(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader webDownloader=new WebDownloader();
webDownloader.downloader(url,name);
System.out.println("下载了文件名为:"+name);
}
public static void main(String[] args) {
TestThread2 t1 = new TestThread2("https://tiebapic.baidu.com/forum/w%3D580%3B/sign=7…au=2025-05-08-05_3ed7200abfc96eeb93da2546e4c4eb29","1.jpg");
TestThread2 t2 = new TestThread2("https://img2024.cnblogs.com/blog/2034232/202401/2034232-20240102162743857-1481497998.png","2.jpg");
TestThread2 t3 = new TestThread2("https://img2024.cnblogs.com/blog/2034232/202401/2034232-20240102162750710-1464502136.png","3.jpg");
t1.start();
t2.start();
t3.start();
}
}
class WebDownloader{
//下载方法
public void downloader(String url,String name){
try {
FileUtils.copyURLToFile(new URL(url),new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
多线程同时操作一个对象:
购买火车票的例子:
public class TestThread5 implements Runnable {
private int ticketNums=10;
@Override
public void run() {
while (true){
if(ticketNums<=1){
break;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票");
}
}
public static void main(String[] args) {
TestThread5 ticket = new TestThread5();
new Thread(ticket,"小明").start();
new Thread(ticket,"小红").start();
new Thread(ticket,"老师").start();
}
}
package com.yang;
import java.util.concurrent.TransferQueue;
//模拟龟兔赛跑
public class TestThread6 implements Runnable {
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(Thread.currentThread().getName().equals("兔子")){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//判断比赛是否结束
boolean flag=gamerOver(i);
//如果比赛结束了,就停止程序
if(flag){
break;
}
System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
}
}
//判断是否完成比赛
private boolean gamerOver(int steps){
//判断是否有胜利者
if(winner!=null){//已经存在了胜利者
return true;
}
{
if (steps==100){
winner = Thread.currentThread().getName();
System.out.println("winner");
}
}
return false;
}
public static void main(String[] args) {
TestThread6 t6 = new TestThread6();
new Thread(t6,"兔子").start();
new Thread(t6,"乌龟").start();
}
}
lambda表达式的表示方法和推导过程:
//定义一个函数式接口
interface ILike{
void lambda();
}
//定义一个实现类
class Like implements ILike{
@Override
public void lambda() {
System.out.println("i like lambda");
}
}
/*
* 推导lambda表达式
* */
public class Testlambda {
//静态内部类
static class Like2 implements ILike {
@Override
public void lambda() {
System.out.println("i like lambda2");
}
}
public static void main(String[] args) {
new Like2().lambda();
new Like().lambda();
//匿名内部类
ILike like = new ILike() {
@Override
public void lambda() {
System.out.println("i like lambda4");
}
};
like.lambda();
//用lambda表达式表示
like=()->{
System.out.println("i like lambda5");
};
like.lambda();
//局部内部类
class Like3 implements ILike {
@Override
public void lambda() {
System.out.println("i like lambda3");
}
}
}
}
使用一个自定义的方法使得进程停止:
package com.yang;
public class TestStop implements Runnable{
//设置一个标志位,主要是让线程识别这个标志
private boolean flag=true;
@Override
public void run() {
int i=0;
//当线程是flag时就一直跑
while (flag){
//另外的线程
System.out.println("run...Thread->"+i++);
}
}
//当线程时false时就停止
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
//在main方法中的线程为主线程
//开启线程(开启一个新线程,走的是run()方法)
TestStop t1= new TestStop();
TestStop t2= new TestStop();
new Thread(t1).start();
new Thread(t2).start();
//循环进入主线程运行(主线程)
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
//当另外一个线程为900的时候,就停止
if(i==900){
t1.stop();
if(t2.flag==true){
t2.stop();
}
System.out.println("线程已经停止了");
//这里使用了一个外部的标志方法使得进程停止了
}
}
}
}
//线程休眠sleep:
public class TestSleep implements Runnable {
private int ticketNums = 10;
@Override
public void run() {
while (true) {
// 调用同步方法
if (!sellTicket()) {
break;
}
}
}
// 同步方法,同一时刻只能有一个线程访问
private synchronized boolean sellTicket() {
if (ticketNums <= 0) {
return false;
}
// 模拟延时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + "—>拿到了第" + ticketNums-- + "票");
return true;
}
public static void main(String[] args) {
TestSleep testSleep = new TestSleep();
new Thread(testSleep, "小红").start();
new Thread(testSleep, "小明").start();
new Thread(testSleep, "小兵").start();
}
}```
关于倒计时和打印当前实时时间:
```java
public class TestSleep2 implements Runnable{
public static void main(String[] args) {
TestSleep2 testSleep2 = new TestSleep2();
new Thread(testSleep2).start();
}
@Override
public void run() {
try {
testDown();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void testDown()throws Exception{
int num=10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num==0){
break;
}
}
}
public static void pritNowDate(){
//打印当前系统时间
Date date = new Date(System.currentTimeMillis());
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
date=new Date(System.currentTimeMillis());
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
线程礼让:yield
public class TestYield {
public static void main(String[] args) {
MyYield myYield = new MyYield();
new Thread(myYield,"A").start();
new Thread(myYield,"B").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"“线程开始执行”");
//线程礼让
Thread.yield();
System.out.println(Thread.currentThread().getName()+"线程停止了");
}
}
线程强制执行(线程插队):
public class TestJoin implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程VIP来了,统统闪开"+i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主线程
for (int i = 0; i < 200; i++) {
if(i==30){//这三十个用户相当于封测用户
thread.join();//插队,而插队这100个人则相当于氪金大佬
}
System.out.println("main"+i);
}
}
}
线程的生命周期:

注意:线程中断或结束,一旦进入死亡状态,就不能再次启动。
线程的优先级:
public class TestPriority {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"=="+Thread.currentThread().getPriority());
MyPriority myPriority = new MyPriority();
Thread t1 = new Thread(myPriority);
Thread t2 = new Thread(myPriority);
Thread t3 = new Thread(myPriority);
Thread t4 = new Thread(myPriority);
Thread t5 = new Thread(myPriority);
Thread t6 = new Thread(myPriority);
Thread t7 = new Thread(myPriority);
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(4);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY);//10
t4.start();
t5.setPriority(8);
t5.start();
t6.setPriority(7);
t6.start();// t6.setPriority(11);//通过查看源码发现,设置优先级为11会报错(大于10)
t7.start();
/*main==5
Thread-0==5
Thread-1==1
Thread-2==4
Thread-3==10
Thread-4==8
Thread-5==7
Thread-6==5
*/
}
}
class MyPriority implements Runnable{
@Override
public void run() {
//注意:并不是优先级高的就会被先调度,优先级低只是意味着获得调度的概率低,优先级低的就不会调度,这都要看cpu的调度情况。System.out.println(Thread.currentThread().getName()+"=="+Thread.currentThread().getPriority());
}
}
守护线程:
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false表示是用户线程,正常的线程都是用户线程
thread.start();
new Thread(you).start();
}
}
//你
class You implements Runnable {
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你一生都开心活着");
}
System.out.println("===goodbye! world=");
}
}
//上帝
class God implements Runnable {
@Override
public void run() {
while (true) {
System.out.println("“上帝保护着你”");
}
}
}```
java
死锁
public class DeadLock {
public static void main(String[] args) {
MakeUp m1 = new MakeUp(0,"灰姑娘");
MakeUp m2 = new MakeUp(1, "白雪公主");
new Thread(m1).start();
new Thread(m2).start();
}
}
//口红
class LipStick {
}
//镜子
class Mirror {
}
class MakeUp implements Runnable {
static LipStick lipstick = new LipStick();
static Mirror mirror = new Mirror();
int Choice;//选择
String girlName;//使用化妆品的人的名字
public MakeUp(int choice, String girlName) {
Choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
}
public void makeup() throws InterruptedException {
//灰姑娘的选择时0,所以灰姑娘先获得镜子的锁,然后灰姑娘想去获得口红的锁,却发现,口红的锁正在被使用
//白雪公主是相同的道理,所以这两个人谁也不让谁拿到对方想要的东西,那便形成了死锁
//就相当于面试官问你,你是否有工作经验,你要工作经验才能来我们这里上班,但你跟面试官说:我来你这工作才有工作经验,要不然哪里来的工作经验
if(Choice==0){
synchronized (lipstick){
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);//此处让进程休眠1秒
}
synchronized (mirror){
System.out.println(this.girlName+"获得镜子的锁");
}
}else {
synchronized (mirror){
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);//此处让进程休眠2秒
}
synchronized (lipstick){
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
关于loca自由锁:
package com.yang;
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket b1 = new BuyTicket();
new Thread(b1,"小红").start();
Thread b2 = new Thread(b1,"小明");
b2.setPriority(9);
b2.start();
new Thread(b1,"黄牛").start();
}
static class BuyTicket implements Runnable{
private int ticket=200;
boolean flag=true;
@Override
public void run() {
while (flag){
try {
buy();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
//synchronized:同步方法,锁的是this
public synchronized void buy() throws Exception{
if (ticket<=0){
flag=false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "买到" + ticket--);
}
}
}
解决多线程通信问题(多个线程如何交互):
生产者和消费者的案例:
package com.yang;
public class TestPC {
public static void main(String[] args) {
SyncContainer syncContainer = new SyncContainer();
new Customer(syncContainer).start();
new Productor(syncContainer).start();
}
}
// 生产者
class Productor extends Thread {
private SyncContainer syncContainer;
public Productor(SyncContainer syncContainer) {
this.syncContainer = syncContainer;
}
@Override
public void run() {
for (int i = 1; i < 100; i++) {
System.out.println("生产了" + i + "只鸡!");
syncContainer.push(new Product(i));
}
}
}
// 消费者
class Customer extends Thread {
private SyncContainer syncContainer;
public Customer(SyncContainer syncContainer) {
this.syncContainer = syncContainer;
}
@Override
public void run() {
for (int i = 1; i < 100; i++) {
Product pop = syncContainer.pop();
System.out.println("消费了第" + pop.getId() + "号产品");
}
}
}
// 产品
class Product {
int id;
public Product(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
// 缓冲区
class SyncContainer {
// 定义容器的大小
Product[] products = new Product[10];
// 设置容器的计数器,并且初始值为 0
int count = 0;
// 生产者放入产品缓冲区应该做什么
public synchronized void push(Product product) {//这个地方传递数组是不合适的,因为不可能每次都传入一个数组,所以这里把数组变成了一个对象,让每次传入进来的都是一个对象这样就是正确的。
// 当容器满时,生产者等待
while (count == products.length) {
try {
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 将产品放入容器
products[count++] = product;//这个地方可以使得产品接受到计数器传递进来的参数
// 通知消费者可以消费了
this.notifyAll();
}
// 消费者可以消费了
public synchronized Product pop() {
// 当容器为空时,消费者等待
while (count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 从容器中取出产品
Product product = products[--count];
// 通知生产者可以生产了
this.notifyAll();
return product;
}
}
信号灯法(标志变量法):
package com.nty.gaoji;
public class TestPC2 {
public static void main(String[] args) {
TV tv = new TV();
new Player(tv).start();
new Watcher(tv).start();
}
}
//生产者-->演员
class Player extends Thread {
TV tv;
public Player(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
this.tv.play("快乐大本营播放中");
} else {
this.tv.play("抖音播放中");
}
}
}
}
//消费者-->观众
class Watcher extends Thread {
TV tv;
public Watcher(TV tv) {
this.tv = tv;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
tv.watch();
}
}
}
//节目
class TV {
//演员表演,观众等待 T
//观众观看,演员等待 F
String voice; //表演的节目
boolean flag = true;
//表演
public synchronized void play(String voice) {
if (!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("演员表演了:" + voice);
//通知观众观看
this.notify();//通知唤醒
this.voice = voice;
this.flag = !this.flag;
}
//观看
public synchronized void watch() {
if (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("观看了:" + voice);
//通知演员表演
this.notify();
this.flag = !this.flag;
}
线程池:
package com.nty.gaoji;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//测试线程池
public class TestPool {
public static void main(String[] args) {
//1.创建服务,创建线程池
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//2.关闭链接
service.shutdown();
}
}
class MyThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
}
多线程的学习到此为止了,有哪里不对的地方请大家多多指点!

浙公网安备 33010602011771号