スレッド通信
複数のスレッドが相互にチェックし、相互に実行をスケジュールするということです
wait();スレッドを待機させ、ブロッキング状態に入ると、自動的にウェイクアップしません
notify();待機中のスレッドをウェイクアップします。複数ある場合は、優先度の高いスレッドをウェイクアップします。
notifyAll();待機中のすべてのスレッドをウェイクアップします
ケース:1〜100の数字を交互に印刷する
1.ロックを使用してRunnableメソッドを実装します
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintNum implements Runnable {
static int num = 0;
static Lock lock = new ReentrantLock();
static Condition con = lock.newCondition();
@Override
public void run() {
while (true) {
try {
lock.lock();
con.signal();//唤醒线程
num++;
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
} else {
lock.unlock();
break;
}
con.await();//线程等待,并释放锁
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
lock.unlock();
}
}
}
}
テストクラス
public class Test {
public static void main(String[] args) {
PrintNum p =new PrintNum();
Thread p1 = new Thread(p);
Thread p2 = new Thread(p);
p1.start();
p2.start();
}
}
2. Runnableを実装する方法、同期を使用して同期コードブロックを装飾する
public class PrintNum implements Runnable{
static int num=0;
@Override
public void run() {
while (true){
synchronized (this){
//implements Runnable 情况下,this只有一个,this可以充当锁
this.notify();//唤醒等待线程 使用锁对象来调用notify(),wait();
if (num<=100){
System.out.println(Thread.currentThread().getName()+":"+num);
num++;
}else{
break;
}
try {
this.wait();//线程等待,并释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
テストクラス
public class Test {
public static void main(String[] args) {
PrintNum p =new PrintNum();
Thread p1 = new Thread(p);
Thread p2 = new Thread(p);
p1.start();
p2.start();
}
}
3. Threadクラスのメソッドを継承し、同期を使用して同期コードブロックを装飾します
public class PrintNum extends Thread {
static int num = 0;
static Object obj =new Object();//继承Thread方式,由于创建了多个对象,需要自己创建一个唯一的对象,充当锁
@Override
public void run() {
while (true) {
synchronized (obj) {
obj.notify();
if (num <= 100) {
System.out.println(Thread.currentThread().getName() + ":" + num);
num++;
} else {
break;
}
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
テストクラス
public class Test {
public static void main(String[] args) {
PrintNum p1 = new PrintNum();
PrintNum p2 = new PrintNum();
p1.start();
p2.start();
}
}
消費者生産者問題
1.カウンタークラス、ストレージクラス
/*柜台中 存放共享数据*/
public class Counter {
int num = 0;//初始物品数量为0
/* 生产商品*/
public synchronized void add() {
if (num == 0) {
num++;
System.out.println("生产一个");
this.notify();//唤醒消费者线程 this表示同一个柜台
} else {
try {
this.wait();//生产者等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/*消费商品 */
public synchronized void sub() {
if (num == 1) {
num--;
System.out.println("消费一个");
this.notify();//唤醒生产者线程 this表示同一个柜台
} else {
try {
this.wait();//消费者等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.プロデューサースレッド
public class Productor extends Thread {
Counter c;
public Productor(Counter c) {
this.c = c;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);//休眠指定的时间
c.add();//调用add方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3.コンシューマースレッド
/*消费者线程*/
public class Customer extends Thread {
Counter c;
public Customer(Counter c) {
this.c = c;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
c.sub();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4.テストクラス
public class Test {
public static void main(String[] args) {
Counter c = new Counter();//创建柜台对象,是生产或者和消费者
Productor p = new Productor(c);
Customer ct = new Customer(c);
p.start();
ct.start();
}
}
jdk8の後にスレッドを作成する2つの方法
1から100までの問題を合計します
1.FutureTaskはタスクを受け入れるために使用されます
import java.util.concurrent.Callable;
public class SumNumThread implements Callable<Integer> {
/*
可以向外界返回一个结果
可以抛出一个异常
*/
@Override
public Integer call() throws Exception {
int sum=0;
for (int i = 1; i <= 100;i++){
sum+=i;
}
return sum;
}
}
public class Test {
public static void main(String[] args) {
//创建任务
SumNumThread sum = new SumNumThread();
//接受任务
FutureTask<Integer> futureTask = new FutureTask(sum);
//创建线程
Thread t = new Thread(futureTask);
t.start();
try {
Integer val = futureTask.get();
System.out.println(val);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
2.ExecutorServiceはスレッドプールを作成します
public class SumNumThread implements Callable<Integer> {
/*
可以向外界返回一个结果
可以抛出一个异常
*/
@Override
public Integer call() throws Exception {
int sum=0;
System.out.println(Thread.currentThread().getName());
for (int i = 1; i <= 100;i++){
sum+=i;
}
return sum;
}
}
public class Test {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
SumNumThread sumNumThread = new SumNumThread();
//将任务交给线程池中线程执行
//线程池中线程不够时,会释放其中的重复利用
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
executorService.submit(sumNumThread);
Future<Integer> f = executorService.submit(sumNumThread);
try {
System.out.println(f.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.shutdown();
}
}