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

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. libcanbus官方主页

    libcanbus canbus(CAN BUS V2.0 B)扩展格式库项目简析 注: 本文如果你已经有linux开发环境 请确保你使用本库时是tag版本号. 该库遵循的协议是SAE J1939-2 ...

  2. Codeforces Round #349 (Div. 2) D. World Tour 暴力最短路

    D. World Tour   A famous sculptor Cicasso goes to a world tour! Well, it is not actually a world-wid ...

  3. Vue.js和Nodejs的关系

    首先vue.js 是库,不是框架,不是框架,不是框架. Vue.js 使用了基于 HTML 的模版语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据. Vue.js 的核心是一个允许你 ...

  4. SMTP协议详解

    简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 是在Internet传输email的事实标准. SMTP是一个相对简单的基于文本的协议.在其之上指定了一条 ...

  5. Hadoop MapReduce编程 API入门系列之统计学生成绩版本2(十八)

    不多说,直接上代码. 统计出每个年龄段的 男.女 学生的最高分 这里,为了空格符的差错,直接,我们有时候,像如下这样的来排数据. 代码 package zhouls.bigdata.myMapRedu ...

  6. C#中DBNull问题

    当数据库中一个字段不是必填项时,在往数据库中插入数据的时候往往会插入一个空字符串就草草了事了.在这里用DBNull可以解决这个问题 /// <summary> /// 插入数据 /// & ...

  7. 开发辅助 | 阿里图标库iconfont入门使用

    目前大多数的互联网公司,前端开发和UI设计师配合中,针对设计师给图的效果图,前端开发工程师不再像往常一样对于细小图标进行切图,取而代之的是引用阿里图标库(http://iconfont.cn/):简单 ...

  8. [Offer收割]编程练习赛36

    逃离单身节 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<vector&g ...

  9. (转载) android studio library生成jar包和aar的方法总结

    android studio library生成jar包和aar的方法总结 标签: android学习文档jar和aar的使用与生成gradle 2016-11-25 10:39 1782人阅读 评论 ...

  10. 集成Bmob推送

    Write By lz:  转发请注明原文地址: http://www.cnblogs.com/lizhilin2016/p/6952217.html Lz 寄语: Bmob 奇葩推送, 大坑, 想要 ...