1、要求线程a执行完才开始线程b, 线程b执行完才开始线程
package com.example.javatest.theardTest.MultiThreadAlgorithm;
/**
* 要求线程a执行完才开始线程b, 线程b执行完才开始线程
*
* join()解释:https://blog.csdn.net/qq_18505715/article/details/79795728
*
* wait() 和 notify() 解释:https://blog.csdn.net/chaozhi_guo/article/details/50249177
*
* join()的作用:主要作用是同步,它可以使得线程之间的并行执行变为串行执行。在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行。
*
* public void joinDemo(){
* //....
* Thread t=new Thread(payService);
* t.start();
* //....
* //其他业务逻辑处理,不需要确定t线程是否执行完
* insertData();
* //后续的处理,需要依赖t线程的执行结果,可以在这里调用join方法等待t线程执行结束
* t.join();
* }
*
*/
public class T1T2T3 {
public static class PrintThread extends Thread{
PrintThread(String name){
super(name);
}
@Override
public void run() {
for(int i = 0; i < 100; i++){
System.out.println(getName() + " : " + i);
}
}
}
public static void main(String[] args){
PrintThread t1 = new PrintThread("a");
PrintThread t2 = new PrintThread("b");
PrintThread t3 = new PrintThread("c");
try {
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 我对于join方法的理解:
*
* join() 的源码:
* public final void join(long millis) throws InterruptedException {
* synchronized(lock) {
* ...
*
* while (isAlive()) {
* lock.wait(0);
* }
* ...
* }
* }
*
* 其实就是main()线程调用join()后,synchronized(lock)语句块,获得lock的锁,
*
* 然后判断如果t1线程isAlive(), 就一直lock.wait(), 让自己(main()线程)阻塞住,
*
* 直到t1线程 !isAlive 后才不wait, 等待着被notify(), 然后t1 die后会调用lock.notifyAll()。
*
*
* 注意:这里lock.wait(0)虽然在t1.join()内,但是join()内的代码不是运行在t1线程中,而是运行在main()线程中,
* t1线程中运行的是其run()方法内的代码。
*
*/
2、两个线程轮流打印数字,一直到100
package com.example.javatest.theardTest.MultiThreadAlgorithm;
/**
* 两个线程轮流打印数字,一直到100
*
* Java的wait()、notify()学习:
* https://blog.csdn.net/boling_cavalry/article/details/77995069
*/
public class TakeTurnsPrint {
public static class TakeTurns {
private static boolean flag = true;
private static int count = 0;
public synchronized void print1() {
for (int i = 1; i <= 50; i++) {
while (!flag) {
try {
System.out.println("print1: wait before");
wait();
System.out.println("print1: wait after");
} catch (InterruptedException e) {
}
}
System.out.println("print1: " + ++count);
flag = !flag;
notifyAll();
}
}
public synchronized void print2() {
for (int i = 1; i <= 50; i++) {
while (flag) {
try {
System.out.println("print2: wait before");
wait();
System.out.println("print2: wait after");
} catch (InterruptedException e) {
}
}
System.out.println("print2: " + ++count);
flag = !flag;
notifyAll();
}
}
}
public static void main(String[] args){
TakeTurns takeTurns = new TakeTurns();
new Thread(new Runnable() {
@Override
public void run() {
takeTurns.print1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
takeTurns.print2();
}
}).start();
}
}
3、写两个线程,一个线程打印1~ 52,另一个线程打印A~Z,打印顺序是12A34B…5152Z
package com.example.javatest.theardTest.MultiThreadAlgorithm;
/**
* 两线程,一个打印数字从1到52,另一个打印字母从A到Z,输出:12A34B56C...5152Z
*/
public class TakeTurnsPrint2 {
private boolean flag;
private int count;
public synchronized void printNum() {
for (int i = 0; i < 26; i++) {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.print(++count);
System.out.print(++count);
notify();
}
}
public synchronized void printLetter() {
for (int i = 0; i < 26; i++) {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.print((char) (65 + i));
notify();
}
}
public static void main(String[] args) {
TakeTurnsPrint2 turnsPrint2 = new TakeTurnsPrint2();
new Thread(new Runnable() {
@Override
public void run() {
turnsPrint2.printNum();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
turnsPrint2.printLetter();
}
}).start();
}
}
4、编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC…
package com.example.javatest.theardTest.MultiThreadAlgorithm;
/**
* 编写一个程序,启动三个线程,三个线程的ID分别是A,B,C;,每个线程将自己的ID值在屏幕上打印5遍,打印顺序是ABCABC...
*/
public class ABCABCABC {
private int flag = 0;
public synchronized void printA() {
for(int i = 0; i < 5; i++) {
while (flag != 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = 1;
System.out.print("A");
notifyAll();
}
}
public synchronized void printB() {
for(int i = 0; i < 5; i++) {
while (flag != 1) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = 2;
System.out.print("B");
notifyAll();
}
}
public synchronized void printC() {
for(int i = 0; i < 5; i++) {
while (flag != 2) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = 0;
System.out.print("C");
notifyAll();
}
}
public static void main(String[] args) {
ABCABCABC abcabcabc = new ABCABCABC();
new Thread(new Runnable() {
@Override
public void run() {
abcabcabc.printA();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
abcabcabc.printB();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
abcabcabc.printC();
}
}).start();
}
}
5、编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加。
/**
* 编写10个线程,第一个线程从1加到10,第二个线程从11加20…第十个线程从91加到100,最后再把10个线程结果相加
*/
public class TenThreadSum {
public static class SumThread extends Thread{
int forct = 0; int sum = 0;
SumThread(int forct){
this.forct = forct;
}
@Override
public void run() {
for(int i = 1; i <= 10; i++){
sum += i + forct * 10;
}
System.out.println(getName() + " " + sum);
}
}
public static void main(String[] args) {
int result = 0;
for(int i = 0; i < 10; i++){
SumThread sumThread = new SumThread(i);
sumThread.start();
try {
sumThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
result = result + sumThread.sum;
}
System.out.println("result " + result);
}
}
6 、三个窗口同时卖票
/**
* 三个窗口同时卖票
*/
/**
* 票
*/
class Ticket {
private int count = 1;
public void sale() {
while (true) {
synchronized (this) {
if (count > 200) {
System.out.println("票已经卖完啦");
break;
} else {
System.out.println(Thread.currentThread().getName() + "卖的第 " + count++ + " 张票");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 售票窗口
*/
class SaleWindows extends Thread {
private Ticket ticket;
public SaleWindows(String name, Ticket ticket) {
super(name);
this.ticket = ticket;
}
@Override
public void run() {
super.run();
ticket.sale();
}
}
public class TicketDemo {
public static void main(String[] args) {
Ticket ticket = new Ticket();
SaleWindows windows1 = new SaleWindows("窗口1", ticket);
SaleWindows windows2 = new SaleWindows("窗口2", ticket);
SaleWindows windows3 = new SaleWindows("窗口3", ticket);
windows1.start();
windows2.start();
windows3.start();
}
}
7、 生产者消费者
7.1 synchronized方式
public class FruitPlateDemo {
private final static String LOCK = "lock";
private int count = 0;
private static final int FULL = 10;
public static void main(String[] args) {
FruitPlateDemo fruitDemo1 = new FruitPlateDemo();
for (int i = 1; i <= 5; i++) {
new Thread(fruitDemo1.new Producer(), "生产者-" + i).start();
new Thread(fruitDemo1.new Consumer(), "消费者-" + i).start();
}
}
class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (LOCK) {
while (count == FULL) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
LOCK.notifyAll();
}
}
}
}
class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (LOCK) {
while (count == 0) {
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
LOCK.notifyAll();
}
}
}
}
}
7.2 ReentrantLock方式 (可以保证顺序)
public class Demo1 {
private int count = 0;
private final static int FULL = 10;
private Lock lock;
private Condition notEmptyCondition;
private Condition notFullCondition;
{
lock = new ReentrantLock();
notEmptyCondition = lock.newCondition();
notFullCondition = lock.newCondition();
}
class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
try {
while(count == FULL) {
try {
notFullCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
notEmptyCondition.signal();
} finally {
lock.unlock();
}
}
}
}
class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
lock.lock();
try {
while(count == 0) {
try {
notEmptyCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
notFullCondition.signal();
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) {
Demo1 demo1 = new Demo1();
for (int i = 1; i <= 5; i++) {
new Thread(demo1.new Producer(), "生产者-" + i).start();
new Thread(demo1.new Consumer(), "消费者-" + i).start();
}
}
}
7.3 BlockingQueue方式
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Demo2 {
private int count = 0;
private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
public static void main(String[] args) {
Demo2 demo2 = new Demo2();
for (int i = 1; i <= 5; i++) {
new Thread(demo2.new Producer(), "生产者-" + i).start();
new Thread(demo2.new Consumer(), "消费者-" + i).start();
}
}
class Producer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
queue.put(1);
System.out.println("生产者 " + Thread.currentThread().getName() + " 总共有 " + ++count + " 个资源");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
queue.take();
System.out.println("消费者 " + Thread.currentThread().getName() + " 总共有 " + --count + " 个资源");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
8、交替打印两个数组
package com.example.javatest.theardTest.MultiThreadAlgorithm;
public class TwoArr {
int[] arr1 = new int[]{1, 3, 5, 7, 9};
int[] arr2 = new int[]{2, 4, 6, 8, 10};
boolean flag;
public synchronized void print1(){
for(int i= 0; i < arr1.length; i++){
while (flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.println(arr1[i]);
notifyAll();
}
}
public synchronized void print2(){
for(int i= 0; i < arr2.length; i++){
while (!flag){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.println(arr2[i]);
notifyAll();
}
}
public static void main(String[] args) {
TwoArr twoArr = new TwoArr();
new Thread(new Runnable() {
@Override
public void run() {
twoArr.print1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
twoArr.print2();
}
}).start();
}
}