java多线程例子_java 多线程简单例子

本文通过多个实例介绍了Java多线程的使用,包括银行存取款问题、生产者消费者问题、购票窗口实现票数同步以及线程中`sleep()`和`wait()`方法的应用,并讨论了死锁的发生条件。通过这些例子,读者可以深入理解Java多线程的同步和通信机制。
摘要由CSDN通过智能技术生成

实现线程的方式是一,继承Thread类,重写父类的run()方法

二,实现接口Runnable中的run()方法。

下面是简单的例子

例子1:银行存取钱问题

package com.direct.demo;

public class Bank {

private static int money;

public int getMoney(){

return money;

}

public void saveMoney(int m){

synchronized (this) {

System.out.println("存钱后的总金额:"+(money+=m));

}

}

public void drawMoney(int m){

synchronized (this) {

Bank bank = new Bank();

if (bank.getMoney()<=0) {

System.out.println("没得钱,取个pi");

}else {

System.out.println("取钱后剩的总金额:"+(money-=m));

}

}

}

public static void main(String[] args) {

Man m1 = new Man();

Women w = new Women();

Thread t1 = new Thread(m1);

Thread t2 = new Thread(m1);

Thread t3 = new Thread(m1);

Thread t4 = new Thread(w);

Thread t5 = new Thread(w);

Thread t6 = new Thread(w);

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

t6.start();

}

}

class Man implements Runnable{

private Bank bank = new Bank();

public void run() {

int m = 100;

int i=0;

while (i<5) {

bank.saveMoney(m);

i++;

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

class Women implements Runnable{

private Bank bank = new Bank();

public void run() {

int m = 100;

int i=0;

//bank.getMoney()>0

while (i<5) {

bank.drawMoney(m);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

i++;

}

}

}

例子2:生产者与消费者问题

package com.direct.demo;

public class Clerk {

private int product = -1;

//这个方法由生产者调用

public synchronized void setProduct(int product){

if (this.product != -1) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.product = product;

System.out.printf("生产者设定 (%d)%n",this.product);

notify();

}

//这个方法由消费者调用

public synchronized int getProduct(){

if (this.product==-1) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

int p = this.product;

System.out.printf("消费者取走 (%d)%n",this.product);

this.product = -1;

notify();

return p;

}

public static void main(String[] args) {

Clerk clerk = new Clerk();

new Thread(new ProducerInt(clerk)).start();

new Thread(new ConsumerInt(clerk)).start();

}

}

class ProducerInt implements Runnable{

private Clerk clerk;

public ProducerInt(Clerk clerk){

this.clerk = clerk;

}

public void run() {

System.out.println("生产者开始生产整数了..................");

for (int product = 1; product <= 10; product++) {

try {

Thread.sleep((int)Math.random()*300);

} catch (InterruptedException e) {

e.printStackTrace();

}

clerk.setProduct(product);

}

}

}

class ConsumerInt implements Runnable{

private Clerk clerk;

public ConsumerInt(Clerk clerk){

this.clerk = clerk;

}

public void run() {

System.out.println("消费者开始消耗整数........");

for (int i = 1; i <=10 ; i++) {

try {

Thread.sleep((int)Math.random()*300);

} catch (InterruptedException e) {

e.printStackTrace();

}

clerk.getProduct();//从店员取走整数

}

}

}

例子3:购票窗口实现票数同步

package com.direct.demo;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class ThreadTicket {

public static void main(String[] args) {

Booking b1 = new Booking("军人售票口");

Booking b2 = new Booking("学生售票口");

Booking b3 = new Booking("老年人售票口");

Booking b4 = new Booking("网上售票口");

b1.start();

b2.start();

b3.start();

b4.start();

}

}

/*

* 多窗口卖票系统。多线程

* 票数为静态的,共享数据

* synchronized(对象){}代码块中的内容是加锁的,

* 即当一个线程在使用时,其他线程不可以进入。

* 使得共享资源数据的安全。

*/

class Booking extends Thread{

public Booking(String name){

super(name);

}

static int ticket = 50;//票数共50张

Lock lock = new ReentrantLock();//明锁

/*

* ReentrantLock根据传入构造方法的布尔型参数实例化出Sync的实现类FairSync和NonfairSync

* ,分别表示公平的Sync和非公平的Sync。

* 由于ReentrantLock我们用的比较多的是非公平锁

ReentrantLock 和synchronized 均为重入锁

* 1. ReenTrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。

2. ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

3. ReenTrantLock提供了一种能够中断等待锁的线程的机制,通过lock.lockInterruptibly()来实现这个机制。

对ReentrantLock的可重入锁这篇博客使用简单的例子进行讲解,  http://blog.csdn.net/yanyan19880509/article/details/52345422

* Lock是个接口,只能实例化它的子类

* 明锁适合高并发,上万

* 暗锁适合并发率不高时,效率高

*/

//重写run方法,

public void run(){

while(ticket>0){

synchronized (Booking.class) {

if (ticket>0) {

System.out.println(super.getName()+"窗口---->卖出的车票号No."+ticket);

ticket--;

}else {

System.out.println(super.getName()+"票已售罄!!!");

}

try {

sleep(100);//睡100毫秒,抛出多线程异常

} catch (InterruptedException e) {

e.printStackTrace();

}

}

/*lock.lock();//加锁,锁定以下代码

if (ticket>0) {

System.out.println(super.getName()+"卖票:"+ticket);

ticket--;

}else {

System.out.println(super.getName()+"票已售罄!!!");

}

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

lock.unlock();//解锁

*/}

}

}

例子4:线程中sleep()和wait()方法测试

package com.direct.demo;

public class TestSleepaWait {

public static void main(String[] args) {

new Thread(new Thread1()).start();

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

new Thread(new Thread2()).start();

}

}

class Thread1 implements Runnable{

public void run() {

synchronized (TestSleepaWait.class) {

System.out.println("Thread1 is start........");

System.out.println("Thread1 is wait..............");

try {

//调用wait方法,线程会放弃对象锁,进入等待对象的等待锁定池

TestSleepaWait.class.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread1 is go on........");

System.out.println("Thread1 is over!");

}

}

}

class Thread2 implements Runnable{

@Override

public void run() {

synchronized (TestSleepaWait.class) {

System.out.println("Thread2 is enter..........");

System.out.println("Thread2 is sleep.......");

//只有针对对象调用notify()方法后本线程才进入对象锁定池

//准备获取对象进入运行状态

TestSleepaWait.class.notify();

//===============

//如果把上句注释掉。即对象锁调用了wait方法,但是没有调用notify

//程序就一致处于挂起状态

try {

Thread.sleep(5000);

//sleep方法暂停执行时间,让出CPU,监控状态保持,

//时间到 了就回复运行, 不会释放对象锁

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread2 is going on..........");

System.out.println("Thread2 is over!!!!");

}

}

}

例子5:sleep()实现对象存取值

package com.direct.demo;

public class ThreadCom {

public static void main(String[] args) {

Person person = new Person();

new Thread(new Producer(person)).start();

new Thread(new Consumer(person)).start();

}

}

class Person{

private String name = "张杰";

private String sex = "男";

public synchronized void put(String name,String sex){

this.name = name;

this.sex = sex;

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

//方法加锁

public synchronized void get(){

System.out.println(name+"----->"+sex);

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

class Consumer implements Runnable{

Person person;

public Consumer(Person person){

this.person = person;

}

public void run() {

while(true){

person.get();

}

}

}

class Producer implements Runnable{

Person person;

public Producer(Person person){

this.person = person;

}

public void run() {

int i = 0;

while (true) {

if (i==0) {

person.put("谢娜", "女");

}else {

person.put("张杰", "男");

}

i = (i+1)%2;//奇数和偶数

}

}

}

例子6:死锁发生条件

在写代码时要避免死锁

package com.direct.demo;

public class DeadLock {

public static void main(String[] args) {

ThreadLock tl = new ThreadLock(true);

ThreadLock tl2 = new ThreadLock(false);

new Thread(tl).start();

new Thread(tl2).start();

}

}

/*

* 死锁的产生条件:

* 1、至少一个资源共享

* 2、至少有一个线程(任务),必须持有资源,且等待获取别的线程持有的资源

* 3、任务抢不到资源

* 4、必须有无限循环

* (1) 互斥条件:一个资源每次只能被一个进程使用。

* (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

* (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

* (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

* 举例说明:不可剥夺资源A、B,进程C、D

* 不可剥夺资源:一个进程申请了之后,不能强制收回,只能进程结束之后自动释放。内存是可剥夺资源

* 进程C申请了资源A,进程D申请了资源B。

* 接下来进程C的操作需要用到资源B,进程D的操作需要用到资源A

* 但是C、D都得不到资源,就引发了死锁

*/

class Lock{

static Object lockOne = new Object();//资源A

static Object lockTwo = new Object();//资源B

}

class ThreadLock implements Runnable{

private boolean flag;

public ThreadLock(boolean flag){

this.flag = flag;

}

@Override

public void run() {

if(flag){

while (true) {

synchronized (Lock.lockOne) {

System.out.println(" this is lockOne");

synchronized (Lock.lockTwo) {

System.out.println("this is lockTwo");

}

}

}

}else {

while (true) {

synchronized (Lock.lockTwo) {

System.out.println(" 这是 lockTwo");

synchronized (Lock.lockOne) {

System.out.println("这是 lockOne");

}

}

}

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值