java多线程顺序执行问题
使用join
假设我要让3个线程按照顺序打印ABC,那么可以使用Join,如果要求多线程按顺序循环打印,则不能用join了
join关键字
join是Thread类的一个方法,启动线程后直接调用。在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。
join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。
具体代码
package googleTest;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runner("A"));
Thread t2 = new Thread(new Runner("B"));
Thread t3 = new Thread(new Runner("C"));
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
}
}
class Runner implements Runnable{
public String name;
Runner(String name)
{
this.name=name;
}
@Override
public void run() {
System.out.println(name+"");
}
}
使用lock和全局变量
</pre>lock时注意unlock就可以啦</p><p class="p1"><pre name="code" class="java">import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest3 {
private static Lock lock=new ReentrantLock();
private static int state = 0;
static class ThreadA extends Thread {
@Override
public void run() {
lock.lock();
if (state % 3 == 0) {
System.out.println("A");
state++;
}
lock.unlock();
}
}
static class ThreadB extends Thread {
@Override
public void run() {
lock.lock();
if (state % 3 == 1) {
System.out.println("B");
state++;
}
lock.unlock();
}
}
static class ThreadC extends Thread {
@Override
public void run() {
lock.lock();
if (state % 3 == 2) {
System.out.println("C");
state++;
}
lock.unlock();
}
}
public static void main(String[] args) {
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}
使用condition
condition关键字
就拿生产者消费者模式来说,当仓库满了的时候,又再执行到 生产者 线程的时候,会把 该 生产者 线程进行阻塞,再唤起一个线程.
但是此时唤醒的是消费者线程还是生产者线程,是未知的。如果再次唤醒的还是生产者线程,那么还需要把它进行阻塞,再唤起一个线程,再此循环,直到唤起的是消费者线程。这样就可能存在 时间或者资源上的浪费,
所以说 有了Condition 这个东西。Condition 用 await() 代替了 Object 的 wait() 方法,用 signal() 方法代替 notify() 方法。注意:Condition 是被绑定到 Lock 中,要创建一个 Lock 的 Condition 必须用 newCondition() 方法。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest2 {
private static Lock lock = new ReentrantLock();
private static int count = 0;
private static Condition A = lock.newCondition();
private static Condition B = lock.newCondition();
private static Condition C = lock.newCondition();
static class ThreadA extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 0)
A.await(); // 会释放lock锁
System.out.print("A");
count++;
B.signal(); // 唤醒相应线程
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 1)
B.await();
System.out.print("B");
count++;
C.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
while (count % 3 != 2)
C.await();
System.out.println("C");
count++;
A.signal();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
new ThreadA().start();
new ThreadB().start();
ThreadC threadC = new ThreadC();
threadC.start();
threadC.join();
System.out.println(count);
}
}
使用信号量
Semaphore关键字
Semaphore为并发包中提供用于控制某资源同时可以被几个线程访问的类。一般用于限制线程访问的资源个数。也可用于线程间的信号传递。 import java.util.concurrent.Semaphore;
public class ThreadTest4 {
private static Semaphore A = new Semaphore(1);
private static Semaphore B = new Semaphore(1);
private static Semaphore C = new Semaphore(1);
static class ThreadA extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
A.acquire();
System.out.print("A");
B.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ThreadB extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
B.acquire();
System.out.print("B");
C.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class ThreadC extends Thread {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
C.acquire();
System.out.println("C");
A.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
B.acquire(); C.acquire(); // 开始只有A可以获取, BC都不可以获取, 保证了A最先执行
new ThreadA().start();
new ThreadB().start();
new ThreadC().start();
}
}