1.任务,进程,线程,多线程
线程开启不一定立即执行,由CPU调度执行。执行的时候需要调用start()方法,不能直接调用run()方法。
使用多线程下载多个图片。
// 实现多线程下载图片
public class TestThread extends Thread{
private String url; // 网络图片地址
private String name; // 保存的文件名
public TestThread(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) {
TestThread thread = new TestThread("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","2.jpg");
TestThread thread2 = new TestThread("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","3.jpg");
TestThread thread3 = new TestThread("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","4.jpg");
thread.start();
thread2.start();
thread3.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方法出现问题");
}
}
}
实现接口的时候再调用方面的区别,Runnable需要多一步把线程对象放到Thread里面
public class Race implements Runnable{
// 胜利者
private static String winner;
@Override
public void run() {
// 来个100米的距离
for (int i = 0; i <= 100; i++) {
// 模拟兔子睡觉
if (Thread.currentThread().getName().equals("兔子") && i%10==0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 判断比赛是否结束
boolean flag = gameOver(i);
// 如果比赛结束,则停止程序
if (flag){
break;
}
System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
}
}
// 判断是否完成比赛
public boolean gameOver(int steps){
// 判断是否为胜利者
if (winner != null){ // 已经存在胜利者
return true;
}else {
if (steps >= 100){
winner = Thread.currentThread().getName();
System.out.println("winner is" + winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
package com.dapeng.callcable;
import com.dapeng.Demo.TestThread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
/**
* @Description 通过Callable接口创建线程
* 好处:
* 1. 可以自定义返回值
* 2. 可以抛出异常
* @Author zhaopeng
* @Date 2023/10/10 16:51
*/
public class testCallable implements Callable<Boolean> {
private String url; // 网络图片地址
private String name; // 保存的文件名
public testCallable(String url,String name){
this.url = url;
this.name = name;
}
@Override
public Boolean call() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downLoader(url,name);
System.out.println("下载了文件名为:" + name );
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
testCallable t1 = new testCallable("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","2.jpg");
testCallable t2 = new testCallable("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","3.jpg");
testCallable t3 = new testCallable("https://img0.baidu.com/it/u=3663508195,2907650417&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1697043600&t=50896d6d3a067f36990a6a406401f13a","4.jpg");
// 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
// 提交执行
Future<Boolean> r1 = ser.submit(t1);
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> r3 = ser.submit(t3);
// 获取结果
Boolean rs1 = r1.get();
Boolean rs2 = r2.get();
Boolean rs3 = r3.get();
// 关闭服务
ser.shutdownNow();
}
}
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方法出现问题");
}
}
}
package com.dapeng.staticProxy;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/10 17:09
*/
// 总结:静态代理模式总结:
// 真实对象和代理对象都要事先同一个接口
// 代理对象要代理真实角色
// 好处:代理对象可以做很多真实对象做不了的事情
// 真实对象专注做自己的事情
public class staticProxy {
public static void main(String[] args) {
You you = new You(); // 真实对象
// 通过对比发现,括号里面的都是接口或者实现接口的类。
new Thread(()-> System.out.println("斤斤计较")).start();
new WeddingCompany(new You()).HappyMarry();
// WeddingCompany weddingCompany = new WeddingCompany(you);
// weddingCompany.HappyMarry();
}
}
interface Marry{
void HappyMarry();
}
// 真实角色
class You implements Marry{
@Override
public void HappyMarry() {
System.out.println("恭喜你结婚了!!!");
}
}
// 代理角色
class WeddingCompany implements Marry{
// 代理谁--》真实目标角色
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public void HappyMarry() {
before();
this.target.HappyMarry(); // 真实对象
after();
}
private void after() {
System.out.println("结婚后,收拾房子");
}
private void before() {
System.out.println("结婚前~~~~收钱");
}
}
package com.dapeng.Demo;
/**
* @Description 测试stop
* 1. 建议线程正常停止----> 利用次数,不建议死循环
* 2. 建议使用标志位----> 设置一个标志位
* 3. 不要使用stop或者destory等过时或者JDK不建议使用的方法
* @Author zhaopeng
* @Date 2023/10/11 10:13
*/
public class TestStop implements Runnable{
// 1. 设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run....Thread" + i++);
}
}
// 2. 设置一个公开的方法停止线程,转换标志
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main" + i);
if (i==100){
// 调用stop的方法,切换标志位,让线程停止
testStop.stop();
System.out.println("线程停止了...");
}
}
}
}
3.2 效果图:
package com.dapeng.Demo;
/**
* @Description
* // 模拟网络延时: 放大问题的发生性
* @Author zhaopeng
* @Date 2023/10/11 10:34
*/
public class TestSleep implements Runnable{
// 票数
private int tickNums = 10;
@Override
public void run() {
while (true){
if (tickNums <= 0){
break;
}
// 模拟延时
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿到了第" + tickNums-- + "票");
}
}
/**
* 倒计时
* @throws InterruptedException
*/
public static void tenDown() throws InterruptedException {
int num = 10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
public static void main(String[] args) {
// TestSleep ticket = new TestSleep();
//
// new Thread(ticket,"小明").start();
// new Thread(ticket,"老师").start();
// new Thread(ticket,"黄牛").start();
try {
tenDown();
} catch (InterruptedException e) {
System.out.println("倒计时出错");
e.printStackTrace();
}
}
}
package com.dapeng.Demo;
/**
* @Description
* 测试礼让线程
* 礼让不一定成功,看cpu心情
* @Author zhaopeng
* @Date 2023/10/11 10:50
*/
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() + "停止线程");
}
}
package com.dapeng.Demo;
/**
* @Description
* 测试Join方法
* 想象为插队
* @Author zhaopeng
* @Date 2023/10/11 10:54
*/
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; 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 < 500; i++) {
if (i == 200){
thread.join();// 插队,main线程阻塞
}
System.out.println("main" + i);
}
}
}
package com.dapeng.Demo;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 11:06
*/
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
System.out.println("要进入睡眠了");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("");
});
// 查看状态:
Thread.State state = thread.getState();
System.out.println(state); // NEW
// 观察启动后
thread.start();
state = thread.getState();
System.out.println("启动后:" + state); // RUN
//只要线程不终止,就一直输出状态
while (state != Thread.State.TERMINATED){
Thread.sleep(100); // 睡眠0.1秒
state = thread.getState(); // 更新线程状态
System.out.println( "睡眠的状态:" + state); // 输入状态
}
}
}
package com.dapeng.Demo;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 11:32
*/
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,"t1");
Thread t2 = new Thread(myPriority,"t2");
Thread t3 = new Thread(myPriority,"t3");
Thread t4 = new Thread(myPriority,"t4");
Thread t5 = new Thread(myPriority,"t5");
// 先设置优先级,再启动
t1.start();
t2.setPriority(1);
t2.start();
t3.setPriority(Thread.MAX_PRIORITY);
t3.start();
t4.setPriority(4);
t4.start();
t5.setPriority(9);
t5.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
}
}
效果:
性能倒置:优先级低的线程被cpu调度,但是优先级高的线程在等待(一般不会出现)
package com.dapeng.Demo;
/**
* @Description
* 守护线程测试
* @Author zhaopeng
* @Date 2023/10/11 11:48
*/
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you =new You();
Thread godThread = new Thread(god,"god");
godThread.setDaemon(true); // 默认是false表示用户线程,正常的线程都是用户线程。。。true表示守护线程
godThread.start();
new Thread(you,"you").start();
}
}
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝再守护你");
}
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("你开心活着");
}
System.out.println("========== GoodBye 世界 ======");
}
}
多个线程操作同一个资源
package com.dapeng.juctest;
/**
* @Description 死锁:多个线程互相抱着对方需要的资源,然后形成僵持
* @Author zhaopeng
* @Date 2023/10/11 16:13
*/
public class DeadLock {
public static void main(String[] args) {
MakeUp makeUp = new MakeUp(0,"女孩");
MakeUp makeUp2 = new MakeUp(2,"女孩222");
makeUp.start();
makeUp2.start();
}
}
// 口红
class Lipstic {
}
// 镜子
class Mirror {
}
// 化妆
class MakeUp extends Thread {
//需要的资源只有一份,用static来保证只有一份
static Lipstic lipstic = new Lipstic();
static Mirror mirror = new Mirror();
int choice; // 选择
String girlname; // 女孩
MakeUp(int choice, String girlname) {
this.choice = choice;
this.girlname = girlname;
}
@Override
public void run() {
// 化妆
try {
makeUp();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeUp() throws InterruptedException {
if (choice == 0){
synchronized (lipstic){// 获得口红锁
System.out.println(this.girlname + "获得口红锁");
Thread.sleep(1000);
synchronized (mirror){
System.out.println(this.girlname + "获得镜子锁");
}
}
// 解决办法,将里面的同步块拿出来
// synchronized (mirror){
// System.out.println(this.girlname + "获得镜子锁");
// }
}else {
synchronized (mirror){// 获得口红锁
System.out.println(this.girlname + "获得镜子锁");
Thread.sleep(2000);
synchronized (lipstic){
System.out.println(this.girlname + "获得口红锁");
}
}
// 解决办法,将里面的同步块拿出来
// synchronized (lipstic){
// System.out.println(this.girlname + "获得口红锁");
// }
}
}
}
效果:程序卡死。
package com.dapeng.juctest;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 16:40
*/
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2).start();
new Thread(testLock2).start();
new Thread(testLock2).start();
}
}
class TestLock2 implements Runnable {
// 票
int tickNums = 10;
// 定义Lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
// 加锁
lock.lock();
if (tickNums>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tickNums--);
}else {
break;
}
}finally {
lock.unlock();
}
}
}
}
package com.dapeng.syn;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 14:26
*/
public class UnsafeBuyTickets {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"张三").start();
new Thread(buyTicket,"里斯").start();
new Thread(buyTicket,"毛里求斯").start();
}
}
class BuyTicket implements Runnable{
// 票
private int ticketNums = 10;
boolean flag = true;// 外部停止方式
@Override
public void run() {
// 买票
while (flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// synchronized 同步方法,锁的是this(本身这个类)。 在需要解决并发问题的时候需要加上synchronized
// private synchronized void buy() throws InterruptedException
private void buy() throws InterruptedException {
// 判断是否有票
if (ticketNums <= 0){
flag = false;
return;
}
// 模拟延时
Thread.sleep(100);
// 买票
System.out.println(Thread.currentThread().getName()+"拿到了第" + ticketNums--+"张票");
}
}
package com.dapeng.syn;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 14:38
*/
public class UnsafeBank {
public static void main(String[] args) {
// 账户
Account account = new Account(100, "结婚基金");
Drawing you = new Drawing(account,50,"You");
Drawing wife = new Drawing(account,100,"Wife");
you.start();
wife.start();
}
}
// 账户
class Account{
int money; // 余额
String name; // 卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
// 银行:模拟取款
class Drawing extends Thread{
Account account; // 账户
// 取了多少钱
int drawingMoney;
// 现在手里多少钱
int nowMoney;
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
// 取钱
@Override
public void run() {
// 如果想解决并发问题,通过添加同步块synchronized(account){}来解决并发问题
// 判断有没有钱
if (account.money - drawingMoney < 0){
System.out.println(this.getName() + "钱不够了,取不了");
return;
}
// 线程睡眠,放大问题发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 卡内余额 = 余额 - 你去的钱
account.money = account.money - drawingMoney;
// 你手里的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name + "余额为:"+account.money);
// Thread.currentThread().getName() = this.getName()
System.out.println(this.getName() + "手里的钱" + nowMoney);
super.run();
}
}
package com.dapeng.syn;
import java.util.ArrayList;
import java.util.List;
/**
* @Description
*
* // 线程不安全的集合(因为多个线程操作list的时候,可能会把同一个位置给覆盖掉)
* @Author zhaopeng
* @Date 2023/10/11 15:11
*/
public class UnsafeList {
public static void main(String[] args) throws InterruptedException {
List<String> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
// 通过添加同步代码块synchronized(list){}就会安全了
list.add(Thread.currentThread().getName());
}).start();
}
Thread.sleep(4000);
System.out.println(list.size());
}
}
效果:(长度不为10000,因为其中有的List集合某个下标被同时覆盖掉)
package com.dapeng.juctest;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @Description
* 测试JUC里面的安全集合
* @Author zhaopeng
* @Date 2023/10/11 15:46
*/
public class TestJuc {
public static void main(String[] args) throws InterruptedException {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
list.add(Thread.currentThread().getName());
}).start();
}
Thread.sleep(3000);
System.out.println(list.size());
}
}
(生产者消费者模式):生产者(Producer) -----> 数据缓存区 -------> 消费者(Consumer)
package com.dapeng.juctest;
/**
* @Description
* 测试:生产者,消费者-----》利用缓冲区解决:管程法
* 生产者,消费者,缓冲区,产品
* @Author zhaopeng
* @Date 2023/10/11 17:03
*/
public class TestPC {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Producer(container).start();
new Consumer(container).start();
}
}
// 生产者
class Producer extends Thread{
SynContainer container;
public Producer(SynContainer container){
this.container = container;
}
// 生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("生产了" + i + "只鸡");
container.push(new Chicken(i));
}
}
}
// 消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了第" + container.pop().i + "只鸡");
}
}
}
// 产品
class Chicken{
int i ;
public Chicken(int i){
this.i = i;
}
}
// 缓冲区
class SynContainer{
// 需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
// 生产者放入产品
public synchronized void push(Chicken chicken){
// 如果容器满了,就需要等待消费者消费
if (count == chickens.length){
// 通知消费者消费,生产等待
try {
System.out.println("生产者---------容器满了,赶紧消费");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果没有满,我们就需要丢入产品
chickens[count] = chicken;
count++;
// 可以通知消费者消费了
System.out.println("生产者---------赶紧消费");
this.notifyAll();
}
// 消费者消费产品
public synchronized Chicken pop(){
// 判断能否消费
if (count == 0) {
// 等待生产者生产,消费者等待
try {
System.out.println("消费者---------容器没了,赶紧生产");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果可以消费,消费
count--;
Chicken chicken = chickens[count];
// 吃完了通知生产者生产
System.out.println("消费者---------我吃完了,赶紧生产");
this.notifyAll();
return chicken;
}
}
package com.dapeng.juctest;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 17:33
*/
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();
}
}
}
// TV
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.notifyAll();
this.voice = voice;
this.flag = !this.flag;
}
// 观看
public synchronized void watch(){
// 如果为真,演员表演,观众等待
if (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 通知观众表演
this.notifyAll();
System.out.println("观众观看了" + voice);
this.flag = !this.flag;
}
}
package com.dapeng.juctest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @Description
* @Author zhaopeng
* @Date 2023/10/11 17:54
*/
public class TestPool {
public static void main(String[] args) {
// 1. 创建服务,创建线程池
// newFixedThreadPool 参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
// 执行
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 < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"--"+ i );
}
}
}
package com.dapeng.juctest;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* @Description 回顾线程的创建
* @Author zhaopeng
* @Date 2023/10/12 8:59
*/
public class TestNew {
public static void main(String[] args) {
new Thread1().start();
new Thread(new Thread2()).start();
FutureTask<String> futureTask = new FutureTask(new Thread3());
new Thread(futureTask).start();
try {
String s = futureTask.get();
System.out.println(s);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
//1. 继承Thread类
class Thread1 extends Thread {
@Override
public void run() {
System.out.println("Thread1");
}
}
// 2. 实现Runnable接口
class Thread2 implements Runnable {
@Override
public void run() {
System.out.println("Thread2");
}
}
// 3. 实现Callable解耦
class Thread3 implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("Thread3");
return "Thread3";
}
}