Day29
多线程
12. 线程的礼让
public class Test01 {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.start();
b.start();
}
}
public class A extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("A:" + i);
}
}
}
public class B extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("B:" + i);
//礼让:让当前线程退出CPU资源,当前线程退出后立刻转入抢资源的状态,可能又会抢到CPU资源
Thread.yield();
}
}
}
13. 线程的合并
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
for (int i = 1; i <=200; i++) {
System.out.println("主线程:" + i);
if(i == 10){
//让t线程加入到当前线程
t.join();
}
}
}
}
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 1; i <=200; i++) {
System.out.println("子线程:" + i);
}
}
}
14.线程的中断
14.1 线程的中断1
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();//子线程
t.start();
//主线程休眠3秒(Main方法就是主线程)
Thread.sleep(3000);
//过时了
t.stop();//立刻停止(缺点:可能会导致功能缺失)
}
}
public class MyThread extends Thread{
@Override
public void run() {
while(true){ //死循环
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
14.2 线程的中断2
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
t.setFlag(false);
}
}
public class MyThread extends Thread{
private boolean flag = true;
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
while(flag){
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
14.3 线程的中断3
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
//改变线程状态
t.interrupt();
}
}
public class MyThread extends Thread{
@Override
public void run() {
//获取线程状态(是否消亡)
// System.out.println(Thread.currentThread().isInterrupted());
while(!Thread.currentThread().isInterrupted()){
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
15.守护线程/后台线程
public class Test01 {
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.setDaemon(true);//将当前线程设置为守护线程
t.start();
for (int i = 1; i <= 5; i++) {
System.out.println("主线程:" + i);
Thread.sleep(1000);
}
}
}
public class MyThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("后台线程默默守护着前台线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
十六、线程局部变量(实现线程范围内的共享变量)-- ThreadLocal
16.1 共享单个数据
public class Test01 {
public static final ConcurrentHashMap<Thread, Integer> map = new ConcurrentHashMap<>();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
int i = 10;
//存数据
map.put(Thread.currentThread(), i);
A a = new A();
B b = new B();
a.println();//10
b.println();//10
}
},"线程1").start();
new Thread(new Runnable() {
@Override
public void run() {
int i = 20;
//存数据
map.put(Thread.currentThread(), i);
A a = new A();
B b = new B();
a.println();//20
b.println();//20
}
}, "线程2").start();
}
}
public class A {
public void println(){
Thread t = Thread.currentThread();
Integer value = Test01.map.get(t);
System.out.println(t.getName() + "里的A类对象获取了数据:" + value);
}
}
public class B {
public void println(){
Thread t = Thread.currentThread();
Integer value = Test01.map.get(t);
System.out.println(t.getName() + "里的B类对象获取了数据:" + value);
}
}
16.2 共享多个数据-- ThreadLocal
public class Test01 {
public static final ThreadLocal<Data> local = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
Data data = Data.getInstance(10,"xxx");
/**
* 存数据
* local.set(data)底层原理:
* 1.获取当前线程对象
* 2.通过当前线程对象获取ThreadLocalMap<ThreadLocal,T>
* 3.map.put(this,t)
*/
local.set(data);
A a = new A();
B b = new B();
a.println();//10
b.println();//10
}
},"线程1").start();
new Thread(new Runnable() {
@Override
public void run() {
Data data = Data.getInstance(20,"yyy");
data = Data.getInstance(30,"zzz");
//存数据
local.set(data);
A a = new A();
B b = new B();
a.println();//20
b.println();//20
}
}, "线程2").start();
}
}
//数据包类
public class Data {
private int i;
private String str;
//有参构造,无参构造,get,set方法省略
//保证每个线程里只有一个Data包对象
public static Data getInstance(int i,String str){
Data data = Test01.local.get();//获取当前线程的Data对象
if(data == null){
data = new Data(i, str);
Test01.local.set(data);
}else{
data.setI(i);
data.setStr(str);
}
return data;
}
@Override
public String toString() {
return "Data [i=" + i + ", str=" + str + "]";
}
}
public class A {
public void println(){
Thread t = Thread.currentThread();
/**
* 获取数据
* local.get()底层原理:
* 1.获取当前线程对象
* 2.通过当前线程对象获取ThreadLocalMap<ThreadLocal,T>
* 3.map.getEntry(this) -> Entry对象
* 4.entry.getValue()
*/
Data value = Test01.local.get();
System.out.println(t.getName() + "里的A类对象获取了数据:" + value);
}
}
public class B {
public void println(){
Thread t = Thread.currentThread();
Data value = Test01.local.get();
System.out.println(t.getName() + "里的B类对象获取了数据:" + value);
}
}
17.线程的生命周期
总结
用,这表明它已经具备了运行条件。
简答题
public class JoinTest2 {
// 1.现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t1");
}
});
final Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
// 引用t1线程,等待t1线程执行完
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2");
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
// 引用t2线程,等待t2线程执行完
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t3");
}
});
t3.start();//这里三个线程的启动顺序可以任意,大家可以试下!
t2.start();
t1.start();
}
}
简答题
class MyThread extends Thread {
volatile boolean stop = false;
public void run() {
while (!stop) {
System.out.println(getName() + " is running");
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("week up from blcok...");
stop = true; // 在异常处理代码中修改共享变量的状态
}
}
System.out.println(getName() + " is exiting...");
}
}
class InterruptThreadDemo3 {
public static void main(String[] args) throws InterruptedException {
MyThread m1 = new MyThread();
System.out.println("Starting thread...");
m1.start();
Thread.sleep(3000);
System.out.println("Interrupt thread...: " + m1.getName());
m1.stop = true; // 设置共享变量为true
m1.interrupt(); // 阻塞时退出阻塞状态
Thread.sleep(3000); // 主线程休眠3秒以便观察线程m1的中断情况
System.out.println("Stopping application...");
}
}