您的位置:首页 > 产品设计 > UI/UE

Java多线程--synchronized ,Condition,BlockingQueue应用实例

2016-07-28 21:38 801 查看
//注:对文中提到的简单概念不熟悉的可自行Google或百度

创建线程有两种方法。继承Thread类或者实现runnable接口。

下面用Thread简单创建两个线程:

public class Thread1 extends Thread {
public void run(){
System.out.println(this.getName());
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
Thread1 thread1 = new Thread1();
Thread1 thread2 = new Thread1();
thread1.start();
thread2.start();
}
}


结果:

main
Thread-0
Thread-1


由于没有指定线程名字,输出的是线程的默认值Thread-n的形式,main是主线程。

考虑一个问题:

用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次.

这是一个著名的多线程面试题,解答如下:

package SyncronizationTest;

/**
* Created by yangl on 2017/5/26.
* 题目:用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次
*/
class Business{
private boolean bShouldSub = true;
public synchronized void sub(){
if (!bShouldSub){//使用while更能使程序更加健壮,防止伪唤醒(下同)
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0;i < 10;i++){
System.out.println("sub thread" + i);
}
bShouldSub = false;
this.notify();
}

public synchronized void main()
{
if (bShouldSub){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0;i < 100;i++){
System.out.println("main thread :" + i);
}
bShouldSub = true;
this.notify();
}
}
public class SyncronizedSwitch {

public static  void main(String [] args){
Business business = new Business();
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 50; i++) {
business.sub();
}
}
}).start();
for (int i = 0; i < 50; i++) {
business.main();
}
}
}


也可以使用阻塞队列BlockingQueue完成

package BlockingQueueTest;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
* Created by yangl on 2017/5/28.
*/
class Business{
BlockingQueue<Integer> blockingQueue1 = new ArrayBlockingQueue<Integer>(1);//队列中只放置一个数据
BlockingQueue<Integer> blockingQueue2 = new ArrayBlockingQueue<Integer>(1);
public Business(){
try {
blockingQueue2.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private boolean bShouldSub = true;
public  void sub(){
try {
blockingQueue1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0;i < 10;i++){
System.out.println("sub thread: " + i);
}
try {
blockingQueue2.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public  void main()
{
try {
blockingQueue2.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0;i < 100;i++){
System.out.println("main thread :" + i);
}
try {
blockingQueue1.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class BlockingQueueTest {

public static  void main(String [] args){
Business business = new Business();
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 50; i++) {
business.sub();
}
}
}).start();
for (int i = 0; i < 50; i++) {
business.main();
}
}
}


Condition的await()方法和signal()方法类似于Object的wait()和notify()方法,也可以完成上述功能。

package ConditionTest;

/**
* Created by yangl on 2017/5/28.
*/

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* Created by yangl on 2017/5/26.
* 题目:用多线程知识完成一个需求,设计一个子线程,运行10次循环后让主线程循环100次,子又循环10次,如此往复50次
*/
class Business{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
private boolean bShouldSub = true;
public  void sub(){
lock.lock();
if (!bShouldSub){//使用while更能使程序更加健壮,防止伪唤醒
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0;i < 10;i++){
System.out.println("sub thread" + i);
}
bShouldSub = false;
condition.signal();
lock.unlock();
}

public  void main()
{
lock.lock();
if (bShouldSub){
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0;i < 100;i++){
System.out.println("main thread :" + i);
}
bShouldSub = true;
condition.signal();
lock.unlock();
}
}
public class ConditionTest {

public static  void main(String [] args){
Business business = new Business();
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 50; i++) {
business.sub();
}
}
}).start();
for (int i = 0; i < 50; i++) {
business.main();
}
}
}


如果是三个线程交替呢?请看下面

package ConditionTest;
/**
* Created by yangl on 2017/5/28.
*/
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* Created by yangl on 2017/5/28.
* 题目:用多线程知识完成一个需求,设计两个子线程sub和sub2,sub运行10次循环后让sub2运行20次,接着主线程循环100次,
* sub又循环10次,sub2又循环20次...如此往复50次
*/
class Business{
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();

//bShouldSub == 0代表main线程,1代表线程sub,2代表线程sub2
private int bShouldSub = 0;
public  void sub(){
lock.lock();
if (bShouldSub != 1){//使用while更能使程序更加健壮,防止伪唤醒
try {
condition1.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0;i < 10;i++){
System.out.println("sub thread" + i);
}
bShouldSub = 2;
condition2.signal();//通知
lock.unlock();
}

public  void main()
{
lock.lock();
if (bShouldSub != 0 ){
try {
condition.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0;i < 100;i++){
System.out.println("main thread :" + i);
}
bShouldSub = 1;
condition1.signal();
lock.unlock();
}

public  void sub2(){
lock.lock();
if (bShouldSub != 2){
try {
condition2.await();
} catch (Exception e) {
e.printStackTrace();
}
}
for (int i = 0;i < 20;i++){
System.out.println("sub2 thread" + i);
}
bShouldSub = 0;
condition.signal();
lock.unlock();
}
}
public class ThreeConditionTest {

public static  void main(String [] args){
Business business = new Business();
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 50; i++) {
business.sub();
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 50; i++) {
business.sub2();
}
}
}).start();
for (int i = 0; i < 50; i++) {
business.main();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: