主线程等待子线程的多种方法

synchronized浅析

sleep 是静态方法,Thread.sleep(xx)谁调用谁睡眠。

join 是合并方法。当前线程调用其它线程xx.join()则等到xx结束才干运行

yield 当前线程让出cpu进入就绪队列。

wait,noitfy,synchronized配合使用对资源进行管理。

synchronized(this)以及非static的synchronized方法(至于static synchronized方法请往下看),仅仅能防止多个线程同一时候运行同一个对象的同步代码段

Sleep

package cn.galc.test;

import java.util.*;

public class TestThread3 {
public static void main(String args[]){
MyThread thread = new MyThread();
thread.start();//调用start()方法启动新开辟的线程
try {
/*Thread.sleep(10000);
sleep()方法是在Thread类里面声明的一个静态方法。因此能够使用Thread.sleep()的格式进行调用
*/
/*MyThread.sleep(10000);
MyThread类继承了Thread类。自然也继承了sleep()方法,所以也能够使用MyThread.sleep()的格式进行调用
*/
/*静态方法的调用能够直接使用“类名.静态方法名”
或者“对象的引用.静态方法名”的方式来调用*/
MyThread.sleep(10000);
System.out.println("主线程睡眠了10秒种后再次启动了");
//在main()方法里面调用另外一个类的静态方法时,须要使用“静态方法所在的类.静态方法名”这种方式来调用
/*
所以这里是让主线程睡眠10秒种
在哪个线程里面调用了sleep()方法就让哪个线程睡眠,所以如今是主线程睡眠了。
*/
} catch (InterruptedException e) {
e.printStackTrace();
}
//thread.interrupt();//使用interrupt()方法去结束掉一个线程的运行并非一个非常好的做法
thread.flag=false;//改变循环条件,结束死循环
/**
* 当发生InterruptedException时。直接把循环的条件设置为false就可以退出死循环,
* 继而结束掉子线程的运行。这是一种比較好的结束子线程的做法
*/
/**
* 调用interrupt()方法把正在运行的线程打断
相当于是主线程一盆凉水泼上去把正在运行分线程打断了
分线程被打断之后就会抛InterruptedException异常。这样就会运行return语句返回。结束掉线程的运行
所以这里的分线程在运行完10秒钟之后就结束掉了线程的运行
*/
}
} class MyThread extends Thread {
boolean flag = true;// 定义一个标记。用来控制循环的条件 public void run() {
/*
* 注意:这里不能在run()方法的后面直接写throw Exception来抛异常,
* 由于如今是要重写从Thread类继承而来的run()方法,重写方法不能抛出比被重写的方法的不同的异常。
* 所以这里仅仅能写try……catch()来捕获异常
*/
while (flag) {
System.out.println("==========" + new Date().toLocaleString() + "===========");
try {
/*
* 静态方法的调用格式一般为“类名.方法名”的格式去调用 在本类中声明的静态方法时调用时直接写静态方法名就可以。 当然使用“类名.方法名”的格式去调用也是没有错的
*/
// MyThread.sleep(1000);//使用“类名.方法名”的格式去调用属于本类的静态方法
sleep(1000);//睡眠的时假设被打断就会抛出InterruptedException异常
// 这里是让这个新开辟的线程每隔一秒睡眠一次,然后睡眠一秒钟后再次启动该线程
// 这里在一个死循环里面每隔一秒启动一次线程,每一个一秒打印出当前的系统时间
} catch (InterruptedException e) {
/*
* 睡眠的时一盘冷水泼过来就有可能会打断睡眠
* 因此让正在运行线程被一些意外的原因中断的时候有可能会抛被打搅中断(InterruptedException)的异常
*/
return;
// 线程被中断后就返回。相当于是结束线程
}
}
}
}

join

package cn.galc.test;

public class TestThread4 {
public static void main(String args[]) {
MyThread2 thread2 = new MyThread2("mythread");
// 在创建一个新的线程对象的同一时候给这个线程对象命名为mythread
thread2.start();// 启动线程
try {
thread2.join();// 调用join()方法合并线程,将子线程mythread合并到主线程里面
// 合并线程后,程序的运行的过程就相当于是方法的调用的运行过程
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i <= 5; i++) {
System.out.println("I am main Thread");
}
}
} class MyThread2 extends Thread {
MyThread2(String s) {
super(s);
/*
* 使用super关键字调用父类的构造方法
* 父类Thread的当中一个构造方法:“public Thread(String name)”
* 通过这种构造方法能够给新开辟的线程命名,便于管理线程
*/
} public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("I am a\t" + getName());
// 使用父类Thread里面定义的
//public final String getName(),Returns this thread's name.
try {
sleep(1000);// 让子线程每运行一次就睡眠1秒钟
} catch (InterruptedException e) {
return;
}
}
}
}

yield

package cn.galc.test;

public class TestThread5 {
public static void main(String args[]) {
MyThread3 t1 = new MyThread3("t1");
/* 同一时候开辟了两条子线程t1和t2。t1和t2运行的都是run()方法 */
/* 这个程序的运行过程中总共同拥有3个线程在并行运行,分别为子线程t1和t2以及主线程 */
MyThread3 t2 = new MyThread3("t2");
t1.start();// 启动子线程t1
t2.start();// 启动子线程t2
for (int i = 0; i <= 5; i++) {
System.out.println("I am main Thread");
}
}
} class MyThread3 extends Thread {
MyThread3(String s) {
super(s);
} public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(getName() + ":" + i);
if (i % 2 == 0) {
yield();// 当运行到i能被2整除时当前运行的线程就让出来让还有一个在运行run()方法的线程来优先运行
/*
* 在程序的运行的过程中能够看到,
* 线程t1运行到(i%2==0)次时就会让出线程让t2线程来优先运行
* 而线程t2运行到(i%2==0)次时也会让出线程给t1线程优先运行
*/
}
}
}
}

生产者消费者(wait,notify)

import java.util.Random;

public class TestAbstract{
public static void main(String[] args) {
Thread [] C = new Thread[5];
Thread [] P = new Thread[5];
Stack stk = new Stack();
for(int i = 0;i<5;i++){
P[i] = new Thread(new Proceduce(stk));
P[i].setName("procedure "+i);
P[i].start();
C[i] = new Thread(new Consumer(stk));
C[i].setName("Consumer "+i);
C[i].start();
}
}
} class Stack{
String table = "abcdefghijklmnopqrstuvwxyz1234567890";
private int cnt = 0;
private char [] data = new char[10];
// private Object cu = new Object();
// private Object po = new Object();
public synchronized void push(char ch){
System.out.println(Thread.currentThread().getName()+" stack'cnt is "+cnt+"");
while(cnt == data.length){
try {
System.out.println(Thread.currentThread().getName()+" must wait");
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
data[cnt++] = ch;
this.notify();
}
public synchronized char pop(){
System.out.println(Thread.currentThread().getName()+" stack'cnt is "+cnt+"");
while(cnt == 0){
try {
System.out.println(Thread.currentThread().getName()+" must wait");
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.notify();
return data[--cnt];
}
}
/**
*
* @author Administrator
*
*/
class Consumer implements Runnable{
private Stack stk = null;
public Consumer(Stack stk){
this.stk = stk;
}
@Override
public String toString() {
return "Consumer [name=" + Thread.currentThread().getName() + "]";
}
public void run() {
// TODO Auto-generated method stub
for(int i = 0;i < 10;i++){
try {
System.out.println(Thread.currentThread().getName()+" get char "+stk.pop());
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }
/**
*
* @author Administrator
*
*/ class Proceduce implements Runnable{
private Stack stk = null;
private Random rdm = new Random();
public Proceduce(Stack stk) {
super();
this.stk = stk;
} public void run() {
// TODO Auto-generated method stub
for(int i = 0;i < 10;i++){
try {
stk.push( stk.table.charAt( rdm.nextInt( stk.table.length() ) ) );
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} }

多线程拨号通话

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList; public class TestAbstract{
static String [] tele = null;
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("user.dir"));
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(".\\src\\tele.txt")));
ArrayList<String> list = new ArrayList<String>();
String tmp;
while((tmp = br.readLine())!=null){
list.add(tmp);
System.out.println(tmp);
}
tele = (String [])list.toArray(new String[0]);
for(String s:tele)
System.out.println(s);
list = null;
br.close();
//获取须要拨打的电话
//创建10个线程工作
ArrayList<Thread> tt = new ArrayList<Thread>();
for(int i = 0;i<10;i++){
Thread t = new Thread(new work());
t.setName("Thread "+(i+1));
t.start();
tt.add(t);
}
for(Thread t:tt){
t.join();
} System.out.println("dial is done");
}
}
class work implements Runnable{
static boolean [] tag = null;
boolean flag;
public work(){
if(tag==null)//线程中止4种方法,这个最安全
tag = new boolean[TestAbstract.tele.length];
flag = true;
}
String dial(){
synchronized (work.class) {
for(int i = 0;i<tag.length;i++){
if(tag[i]==false){
tag[i] = true;
return TestAbstract.tele[i];
}
}
}
return null;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(flag){
String str = dial();
if(str==null){
flag = false;
break;
}
System.out.println(Thread.currentThread().getName() + " start dial " + str);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " dial "+str+" success");
} } }

Semaphore

ref

public class asdf {

    public static void main(String[] args) {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool();
// 仅仅能5个线程同一时候訪问
final Semaphore semp = new Semaphore(5);
// 模拟20个client訪问
for (int index = 0; index < 20; index++) { final int NO = index; Runnable run = new Runnable() {
public void run() {
try {
// 获取许可
semp.acquire();
System.out.println("Accessing: " + NO);
Thread.sleep((long) (Math.random() * 10000));
// 訪问完后,释放
semp.release();
System.out.println("-----------------"+semp.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
// 退出线程池
exec.shutdown();
}
}

測试整理

public class asdf {
/**
* 生产者消费者模型,通过对同一个对象操作来进行同步。
* 生产者之间,消费者之间。生产消费者间相互排斥
*/
static Object consumerObj = new Object();
static Object providerObj = new Object(); class Consumer implements Runnable { @Override public void run() {
consumer();
} void consumer() {
System.out.println(Thread.currentThread().getName() + " start");
// 对Data进行相互排斥 ,也能够进行Semaphore.require,release 或者Lock 或者AtomicBoolean
synchronized (Data.data) {
while (Data.data.isEmpty()) {
try {
System.out.println(
Thread.currentThread().getName() + " data is empty,wait seconds");
Data.data.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Data.data.notifyAll();
}
}
System.out.println(
Thread.currentThread().getName() + " Consumer data:" + Data.data.poll());
Data.data.notifyAll();
}
System.out.println(Thread.currentThread().getName() + " end");
}
} class Provider implements Runnable {
@Override public void run() {
provider();
} void provider() {
System.out.println(Thread.currentThread().getName() + " start");
synchronized (Data.data) {
while (Data.data.size() >= Data.dataLength) {
try {
System.out.println(
Thread.currentThread().getName() + " data is full,wait seconds");
Data.data.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Data.data.notifyAll();
}
}
int d = (int) (Math.random() * 1000);
Data.data.offer(d);
System.out.println(Thread.currentThread().getName() + " Provider data:" + d);
Data.data.notifyAll();
}
System.out.println(Thread.currentThread().getName() + " end");
}
} static class Data {
static final Queue<Integer> data = new LinkedList<Integer>();
static final int dataLength = 10;
} static int wr;
static int readCnt = 0;
static int writeCnt = 0;
Semaphore readerSemaphore = new Semaphore(1);
Semaphore writerSemaphore = new Semaphore(1);
Semaphore readCntSemaphore = new Semaphore(1);
Semaphore writeCntSemaphore = new Semaphore(1); class Writer1 implements Runnable {
void writer(int num) {
try {
writerSemaphore.acquire();
wr = num;
System.out.println(Thread.currentThread().getName() + " write num:" + num);
Thread.sleep((long) (Math.random() * 1000));
writerSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override public void run() {
writer((int) (Math.random() * 1000));
}
} class Reader1 implements Runnable {
int reader() {
int ret = 0;
try {
readerSemaphore.acquire();
if (readCnt == 0)
writerSemaphore.acquire(); // 没有读者在读,则可能存在写者,因此在这里尝试获取锁
readCnt++;
readerSemaphore.release(); ret = wr;
System.out.println(Thread.currentThread().getName() + " read num:" + ret);
Thread.sleep((long) (Math.random() * 1000));
readerSemaphore.acquire();
readCnt--;
if (readCnt == 0)
writerSemaphore.release();
readerSemaphore.release();
return ret;
} catch (InterruptedException e) {
e.printStackTrace();
return ret;
}
} @Override public void run() {
reader();
}
} class Reader2 implements Runnable {
public int reader() {
int ret=0;
try {
readerSemaphore.acquire();
readCntSemaphore.acquire();
readCnt++;
if(readCnt == 1){
writerSemaphore.acquire();
}
readCntSemaphore.release();
readerSemaphore.release(); ret = wr;
System.out.println(Thread.currentThread().getName() + " read data:" + ret);
Thread.sleep((long) (Math.random() * 1000)); readCntSemaphore.acquire();
readCnt--;
if(readCnt == 0){
writerSemaphore.release(); // 读写相互排斥
}
readCntSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
return ret;
}
@Override public void run() {
reader();
}
} class Writer2 implements Runnable { public void writer(int num) {
try {
writeCntSemaphore.acquire();
writeCnt++;
if(writeCnt == 1){
readerSemaphore.acquire(); // 读写相互排斥
}
writeCntSemaphore.release(); writerSemaphore.acquire();
wr = num;
System.out.println(Thread.currentThread().getName() + " write data:" + num);
Thread.sleep((long) (Math.random() * 1000)); writerSemaphore.release(); writeCntSemaphore.acquire();
writeCnt--;
if(writeCnt == 0){
readerSemaphore.release(); // 读写相互排斥
}
writeCntSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override public void run() {
writer((int) (Math.random() * 1000));
}
} static void ProviderConsumerTest() {
// 线程池
ExecutorService exec = Executors.newCachedThreadPool(); asdf tt = new asdf();
for (int index = 0; index < 5; index++) {
Thread t = new Thread(tt.new Consumer());
t.setName("Consumer" + String.valueOf(index));
exec.execute(t);
}
for (int index = 0; index < 5; index++) {
Thread t = new Thread(tt.new Provider());
t.setName("Provider" + String.valueOf(index));
exec.execute(t);
}
// 退出线程池
exec.shutdown();
} static void readerPriority() {
asdf tt = new asdf();
Random random = new Random();
random.setSeed(System.currentTimeMillis());
for (int i = 0; i < 20; i++) {
//随机生成读者和写者
if (random.nextBoolean()) {
Thread t = new Thread(tt.new Reader1());
t.start();
} else {
Thread t = new Thread(tt.new Writer1());
t.start();
}
}
}
static void writerPriority() {
asdf tt = new asdf();
Random random = new Random();
random.setSeed(System.currentTimeMillis());
for (int i = 0; i < 20; i++) {
//随机生成读者和写者
if (random.nextBoolean()) {
Thread t = new Thread(tt.new Reader2());
t.start();
} else {
Thread t = new Thread(tt.new Writer2());
t.start();
}
}
}
public static void main(String[] args) {
// 生产者消费者演示样例
// ProviderConsumerTest();
// 读者优先
// readerPriority();
// 写者优先
writerPriority();
}
}

Java多线程演示样例(模拟通话,sleep,join,yield,wait,notify,Semaphore)的更多相关文章

  1. Java线程演示样例 - 继承Thread类和实现Runnable接口

    进程(Process)和线程(Thread)是程序执行的两个基本单元. Java并发编程很多其它的是和线程相关. 进程 进程是一个独立的执行单元,可将其视为一个程序或应用.然而,一个程序内部同事还包括 ...

  2. java设计模式演示样例

    创建模式 1.工厂方法模式(Factory Method)  将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相 ...

  3. java监听器演示样例

    监听器的原理是观察者模式.就像明星(事件源)聚拢了一群粉丝(观察者).当明星有啥举动的时候会通过粉丝们报道出去. 订阅信息.计算器button都是该原理的应用. 以下写了一个监听器的小样例: pack ...

  4. Java 8 时间日期库的20个使用演示样例

    除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务演示样例来学习怎样使用Java 8的这套API.Java对日 ...

  5. HTTP基本认证(Basic Authentication)的JAVA演示样例

    大家在登录站点的时候.大部分时候是通过一个表单提交登录信息.可是有时候浏览器会弹出一个登录验证的对话框.例如以下图,这就是使用HTTP基本认证.以下来看看一看这个认证的工作过程:第一步:  clien ...

  6. Android之——多线程下载演示样例

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46883927 一.概述 说到Android中的文件下载.Android API中明 ...

  7. java 覆盖hashCode()深入探讨 代码演示样例

    java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...

  8. java并行调度框架封装及演示样例

    參考资料:  阿里巴巴开源项目 CobarClient  源代码实现. 分享作者:闫建忠 分享时间:2014年5月7日 ---------------------------------------- ...

  9. Java连接redis的使用演示样例

    Java连接redis的使用演示样例 Redis是开源的key-value存储工具,redis通经常使用来存储结构化的数据,由于redis的key能够包括String.hash.listset和sor ...

随机推荐

  1. 0x66 Tarjan算法与无向图联通性

    bzoj1123: [POI2008]BLO poj3694 先e-DCC缩点,此时图就变成了树,树上每一条边都是桥.对于添加边的操作,相当于和树上一条路径构环,导致该路径上所有边都不成为桥.那么找这 ...

  2. 0x63树的直径与最近公共祖先

    凉 bzoj1999 先把树的直径求出来,从左往右枚举,对于当前位置i,找到满足限制并且最远的点j,当前位置最大值就是max(i~j区间内除直径外的子树路径长度最大值,1~i的长度,j~n的长度) 然 ...

  3. CodeForces--621A--Wet Shark and Odd and Even(数学水题)

    Wet Shark and Odd and Even Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & ...

  4. [POJ 2282] The Counting Problem

    [题目链接] http://poj.org/problem?id=2282 [算法] 数位DP [代码] #include <algorithm> #include <bitset& ...

  5. git如何解决冲突(master分支的上的冲突--太岁头上动土)

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 git是什么就不废话了,详情点击 出现以下情况怎么解决? 有个index.ts文件 export const ENV = ...

  6. BZOJ 1531 二进制优化多重背包

    思路: 讲道理我应该写单调队列优化多重背包的 但是我不会啊 但是我现在! 还不会啊 我就写了个二进制优化的.. 过了 //By SiriusRen #include <cstdio> #i ...

  7. selenium 最大化浏览器是解决浏览器和驱动不匹配的方法如下

    那么要想selenium成功的操作chrome浏览器需要经历如下步骤: 1.下载ChromeDriver驱动包(下载地址: http://chromedriver.storage.googleapis ...

  8. (转) 50个CSS技巧

    这里我工作中收集了10个很不错的CSS技巧,你可以用在你的项目上.它可以帮你很好地整理你的元素并让他们看起来蛮酷的.下面开始我们的内容,希望你会喜欢它.下面是我收集的CSS技巧,希望能帮助到你,感觉收 ...

  9. LSTM比较RNN

    LSTM只能避免RNN的梯度消失(gradient vanishing),但是不能对抗梯度爆炸问题(Exploding Gradient). 梯度膨胀(gradient explosion)不是个严重 ...

  10. ZJOI2015 幻想乡战略游戏 动态点分治_树链剖分_未调完

    Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来, ...