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();
}
}