1、使用semaphore对象
public class ThreadCommunication {
private static int num;
/**
* semaphore :信号对象,可在线程中阻塞多个线程,释放多个线程,线程的释放是通过permit来完成的
* semaphore.acquire()来释放线程,若semaphore中没有permit,则阻塞等待有permit为止
* semaphore.release(int permits) ===>release()方法用于释放多个permit信号
*/
private static Semaphore semaphore = new Semaphore(0);
public static void main(String[] args) {
final Thread threadA = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
num = 1;
//初始化完成后,释放两个permit
semaphore.release(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
//semaphore 获取permit,若semaphore对象中没有permit,则会发生阻塞并等待到有permit为止
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量" + (num++));
}
});
Thread threadC = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "获取到了ThreadB修改的num值: " + num);
}
});
// 同时开启线程
threadA.start();
threadB.start();
threadC.start();
}
}
2 、使用线程内部的join()方法
public class ThreadCommunication2 {
private static int num;
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
//完成类成员变量的赋值
num = 1;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":获得了类成员变量(0为失败)"+(num++));
}
});
Thread threadC = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":获得修改后的类成员变量"+num);
}
});
// 同时开启三个线程
threadA.start();
threadA.join(); //wait for this thread to die
threadB.start();
threadB.join();
threadC.start();
}
}
3 、使用线程池技术Executors.newSingleThreadExecutor()方法
public class ThreadCommunication3 {
private static int num;
public static void main(String[] args) throws InterruptedException {
Thread threadA = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
//完成类成员变量的赋值
num = 1;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":获得了类成员变量(0为失败)"+(num++));
}
});
Thread threadC = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":获得修改后的类成员变量"+num);
}
});
ExecutorService pool = Executors.newSingleThreadExecutor();
// 同时开启三个线程
pool.execute(threadA);
pool.execute(threadB);
pool.execute(threadC);
}
}
4、使用线程间的通讯(一)
* 模拟三个线程,A||B||C A用来初始化成员变量,供B和C使用
* 实现:使用的是线程之间的通讯wait()和notify()方法
* 上述两种方法要通过同步锁实现,线程之间的通讯也需要同一把锁
*/
public class ThreadCommunication4 {
private static int num;
private static boolean flag = false;
public static void main(String[] args) {
final Object obj = new Object();
Thread threadA = new Thread(new Runnable() {
public void run() {
synchronized (obj) {
while (flag) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
num = 1;
System.out.println("num完成初始化");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
flag = true;
obj.notify();
}
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
synchronized (obj) {
while (!flag) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
obj.notify();
}
System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量(ThreadB)" + (num++));
}
}
});
Thread threadC = new Thread(new Runnable() {
public void run() {
synchronized (obj) {
while (!flag) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
obj.notify();
}
System.out.println(Thread.currentThread().getName() + "(ThreadC)获取到了的num值: " + num);
}
}
});
// 同时开启线程
threadA.start();
threadB.start();
threadC.start();
}
}
5 、使用线程间的通讯方式(二)
* 模拟三个线程,A||B||C A用来初始化成员变量,供B和C使用
* 实现:使用await()和signal() 代替synchronize()同步锁
*/
public class ThreadCommunication5 {
private static int num;
// private static boolean flag = false;
public static void main(String[] args) {
final ReentrantLock lock = new ReentrantLock();
final Condition c1 = lock.newCondition();
final Condition c2 = lock.newCondition();
Thread threadA = new Thread(new Runnable() {
public void run() {
lock.lock();
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
num = 1;
System.out.println("num完成初始化");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
c2.signalAll();
lock.unlock();
}
}
});
Thread threadB = new Thread(new Runnable() {
public void run() {
lock.lock();
c1.signal();
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
c2.signalAll();
lock.unlock();
}
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "====" + i);
}
System.out.println(Thread.currentThread().getName() + ":获取到了类成员变量(ThreadB)" + (num++));
}
});
Thread threadC = new Thread(new Runnable() {
public void run() {
lock.lock();
c1.signal();
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
c2.signalAll();
lock.unlock();
}
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "====" + i);
}
System.out.println(Thread.currentThread().getName() + "(ThreadC)获取到了的num值: " + num);
}
});
// 同时开启线程
threadA.start();
threadB.start();
threadC.start();
}
}