目录
1.累加count
使用两个线程来累加 count 的值
每个线程循环 1w 次,累加变量 count 的值,count 默认值为 0,注意线程安全问题。
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
//创建一个锁对象
Object locker = new Object();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized(locker) {
count++;
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronized(locker) {
count++;
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(count);
}
或者利用 join() 方法 注意写的顺序就不用加锁 线程也是安全的
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
count++;
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
count++;
}
});
//注意join的顺序及作用
t1.start();
t1.join();
t2.start();
t2.join();
System.out.println(count);
}
2.顺序打印 |
有三个线程,分别只能打印A,B和C
要求按顺序打印ABC,打印10次
输出示例:
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
ABC
public static void main(String[] args) throws InterruptedException {
//创建三个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
Object locker3 = new Object();
//线程一
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker1) {
try {
locker1.wait();
System.out.print("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker2) {
locker2.notify();
}
}
});
//线程二
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker2) {
try {
locker2.wait();
System.out.print("B");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker3) {
locker3.notify();
}
}
});
//线程三
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (locker3) {
try {
locker3.wait();
System.out.println("C");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (locker1) {
locker1.notify();
}
}
});
//启动线程
t1.start();
t2.start();
t3.start();
//让线程先睡眠1秒 主线程往下执行来唤醒锁locker1
Thread.sleep(1000);
synchronized (locker1) {
locker1.notify();
}
}
3.死锁代码
所谓的死锁就是线程一拥有锁1,线程二拥有锁2,双方在拥有自身锁的同时尝试获取对方的锁,最终两个线程就会进入无线等待的状态,这就是死锁。
public static void main(String[] args) {
//创建两个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
//创建两个线程
Thread t1 = new Thread(() -> {
synchronized (locker1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
synchronized (locker2) {
System.out.println(Thread.currentThread().getName());
}
}
},"t1");
Thread t2 = new Thread(() -> {
synchronized (locker2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
synchronized (locker1) {
System.out.println(Thread.currentThread().getName());
}
}
},"t2");
t1.start();
t2.start();
}
4.顺序打印 ||
有三个线程,线程名称分别为:a,b,c。
每个线程打印自己的名称。
需要让他们同时启动,并按 c,b,a的顺序打印
public static void main(String[] args) throws InterruptedException {
//创建三个锁对象
Object locker1 = new Object();
Object locker2 = new Object();
Object locker3 = new Object();
//线程一
Thread c = new Thread(() -> {
System.out.print(Thread.currentThread().getName()+" ");
},"c"); //c写在这里 线程名
//线程二
Thread b = new Thread(() -> {
try {
//阻塞等待线程c执行完
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(Thread.currentThread().getName()+" ");
},"b"); //b写在这里 线程名
//线程三
Thread a = new Thread(() -> {
try {
//阻塞等待线程b执行完
b.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(Thread.currentThread().getName()+" ");
},"a"); //a写在这里 线程名
//启动线程
a.start();
b.start();
c.start();
}
5.在子线程执行完毕后再执行主线程代码。
有20个线程,需要同时启动。
每个线程按0-19的序号打印,如第一个线程需要打印0
请设计代码,在main主线程中,等待所有子线程执行完后,再打印 ok
public class test {
public static void main(String[] args) throws InterruptedException {
Thread[] threads = new Thread[20];
for (int i=0;i<20;i++) {
final int tmp = i;
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(tmp); //内部类使用外部的变量,必须是final修饰
}
});
}
for (Thread i:threads) {
i.start();
}
for (Thread i:threads) {
i.join();
}
System.out.println("OK");
}
}