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

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 list = new ArrayList();

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 tt = new ArrayList();

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

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 data = new LinkedList();

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多线程教学演示系统_Java多线程演示样例(模拟通话,sleep,join,yield,wait,notify,Semaphore)...相关推荐

  1. [附源码]计算机毕业设计JAVA教师教学评价系统

    [附源码]计算机毕业设计JAVA教师教学评价系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(Inte ...

  2. java毕业设计教学辅助系统mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计教学辅助系统mybatis+源码+调试部署+系统+数据库+lw java毕业设计教学辅助系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B/S架构 开 ...

  3. [附源码]计算机毕业设计JAVA高校教师教学助手系统的设计与实现

    [附源码]计算机毕业设计JAVA高校教师教学助手系统的设计与实现 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Ecli ...

  4. java多线程的实现方式_Java 多线程(一)——多线程的实现方式

    一.前言 Java 异常的处理方式与自定义异常 我们已经讲完了,从今天开始我们来学习多线程. 二.与多线程相关的概念 2.1.并发与并行并发:指两个或多个事件在同一个时间段内发生,具体如下图所示: 并 ...

  5. java 多线程使用线程池_Java多线程:如何开始使用线程

    java 多线程使用线程池 什么是线程? (What is a Thread?) A thread is a lightweight process. Any process can have mul ...

  6. java 创建日程到期提醒_Java 多线程与高并发,基础概念回顾

    Java多线程 基础 想当初上大学时,最开始的计算机入门课是用Java语言教学的,也就是说,人生的第一行"Hello World"程序是用Java写的.可惜到现在在组里写Web项目 ...

  7. java 线程强制停止线程_java多线程之停止线程

    在多线程开发中停止线程是非常重要的技术点. 停止线程在Java语言中并不像break语句那样干脆.须要一些技巧性的处理. 一.  异常法 採用异常法来停止一个线程.首先我们须要了解一下两个方法的使用方 ...

  8. 基于jsp(java)网络教学平台系统的设计与实现

    欢迎添加微信互相交流学习哦! 项目源码:https://gitee.com/oklongmm/biye2 摘 要 远程教育作为现代教育技术的形式,给教育思想与技术带来了革命性的变革,己经成为现代教育的 ...

  9. 基于jsp(java)网络教学平台系统的设计和开发(含源文件)

    获取项目源文件,联系Q:1225467431,可指导毕设,课设 摘 要 远程教育作为现代教育技术的形式,给教育思想与技术带来了革命性的变革,己经成为现代教育的必然要求.远程教育要得以顺利.高效的实施, ...

  10. [附源码]java毕业设计教学辅助系统

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

最新文章

  1. PTP4L 简化版本OC模式
  2. windows 网络规划
  3. C语言——把结构体数据封装成TLV格式的数据
  4. IT自动化:自动化的网络管理变得很重要
  5. 使用cloudera manager安装Hue服务【详细步骤】
  6. python常见面试题目(面试官最爱问的python面试题)
  7. Exploit开发系列教程-Exploitme2 (Stack cookies SEH)
  8. 海量数据库解决方案2011022101
  9. 随机数大家都会用,但是你知道生成随机数的算法吗?
  10. 有没有知道如何连接DB2的数据库?
  11. 联想m7400 linux驱动下载,联想M7400W驱动-联想M7400W打印机驱动下载 v1.6.0.0官方版--pc6下载站...
  12. Flink 动态配置(参数 算子 CEP)
  13. 针对文本文件单行连续多字符内容根据分隔符号转多行方法
  14. Steam网页版/手机端显示“短期内来自您网络的失败登陆过多,请稍后再试”
  15. 如果你打算看完Linux内核源码,可能穷尽一生都做不出一个系统
  16. 天玑9000和苹果a15哪个好
  17. 微软 Office Online 在线查看word,pdf, xls,ppt 文档
  18. strcpy()、strncpy()函数
  19. Video标签的基本使用
  20. jQuery的change()事件

热门文章

  1. 【bug:鳄梨】【上线前修改其他bug急着提交造成的bug】
  2. js 根据某属性取出数组中对应的对象
  3. c 程序设计语言第一次作业,重大2017年C++程序设计语言第一次作业(含答案).doc...
  4. 五大特点_皮肤肤质五大分类及其特点
  5. Python爬虫教程-22-lxml-etree和xpath配合使用
  6. 奔小康赚大钱 HDU - 2255(最大权值匹配 KM板题)
  7. 重写iframe内联框架中的内容
  8. bcp sqlcmd bulkinsert在unicode问题,Unexpected EOF encountered in BCP data-file
  9. DevExpress学习之Gridcontrol
  10. Shell中的grep、awk和sed的常用命令和语法