`
从此醉
  • 浏览: 1045745 次
  • 性别: Icon_minigender_1
  • 来自: US
社区版块
存档分类
最新评论

Java线程小结(二)

 
阅读更多

六、interrupt()
使该线程中断,如果一个线程抛出异常,可以用interrupt在catch里中断该线程.

七、构造方法
Thread()
分配新的Thread对象。
Thread(Runnable target)
分配新的Thread对象。
Thread(Runnable target, String name)
分配新的Thread对象。
Thread(String name)

八、常用方法
static Thread currentThread()
返回对当前正在执行的线程对象的引用。

String getName()
返回该线程的名称。

void setName(String name)
改变线程名称,使之与参数name相同。

int getPriority()
返回线程的优先级。
void setPriority(int newPriority)
更改线程的优先级。

void interrupt()
中断线程。

boolean isAlive()
测试线程是否处于活动状态。

boolean isDaemon()
测试该线程是否为守护线程。

void join()
等待该线程终止。
void join(long millis)
等待该线程终止的时间最长为millis毫秒。

void run()
如果该线程是使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法;否则,该方法不执行任何操作并返回。

void setDaemon(boolean on)
将该线程标记为守护线程或用户线程。

void start()
使该线程开始执行;Java虚拟机调用该线程的run方法。

static void yield()
暂停当前正在执行的线程对象,并执行其他线程。


九、线程组

ThreadGroup类
ThreadGroup类来表示线程组,它可以对一批线程进行分类管理。Java允许程序直接对线程组进行控制,

案例:

package com.xiaomo.thread;
public class ThreadGroupTest {
public static void main(String[] args) throws InterruptedException {
//获取主线程所在的线程组,这是多有线程默认的线程组
ThreadGroup  mainGroup = Thread.currentThread().getThreadGroup();
System.out.println("主线程组的名称:"+mainGroup.getName());
System.out.println("主线程组是否是后台线程组:"+mainGroup.isDaemon());
new MyThread("新线程组");
ThreadGroup tg = new ThreadGroup("新线程组");
tg.setDaemon(true);
System.out.println("tg线程组是否是后台线程组:"+tg.isDaemon());
MyThread tt = new MyThread(tg, "tg组的线程甲");
tt.start();
//中断线程组中的所有进程
// tg.interrupt();
// Thread.sleep(20);
//返回正在活动的线程数
// System.out.println(tg.activeCount());
//设置线程组的优先级
// tg.setMaxPriority(Thread.MAX_PRIORITY);
//获取线程组的优先级
// System.out.println(tg.getMaxPriority());
new MyThread(tg, "tg组的线程乙").start();
}
}
class MyThread extends Thread {
// 提供指定先成名的构造器
public MyThread(String name) {
super(name);
}
// 提供指定线程名,线程组的构造器
public MyThread(ThreadGroup group, String name) {
super(group, name);
}
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(getName() + "线程的i变量" + i);
}
}
}

十、线程同步
Java里的多线程编程常常容易突然出现错误情况,这是由于系统的线程调度具有一定随机性,即使程序在运行过程中偶尔出现问题,是由于我们编程不当所引起的。当使用多个线程来访问同一个数据时,非常容易出现线程安全问题,所以我们用同步机制来解决这些问题。

实现同步机制有两个方法:
1,同步代码块:
synchronized(同一个数据){}同一个数据:就是N条线程同时访问一个数据
2,同步方法:
public synchronized数据返回类型方法名(){}
就是使用synchronized来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是this也就是该对象的本身,通过使用同步方法,可非常方便的将某类变成线程安全的类,具有如下特征:
1,该类的对象可以被多个线程安全的访问。
2,每个线程调用该对象的任意方法之后,都将得到正确的结果。
3,每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。
注:synchronized关键字可以修饰方法,也可以修饰代码块,但不能修饰构造器,属性等。

实现同步机制注意以下几点:安全性高,性能低,在多线程用。性能高,安全性低,在单线程用。
1,不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。
2,如果可变类有两种运行环境,当线程环境和多线程环境则应该为该可变类提供两种版本:线程安全版本和线程不安全版本(没有同步方法和同步块)。在单线程中环境中,使用线程不安全版本以保证性能,在多线程中使用线程安全版本.


Java.lang.object里的三个方法wait() notify() notifyAll()
wait方法导致当前线程等待,直到其他线程调用同步监视器的notify方法或notifyAll方法来唤醒该线程。
wait(mills)方法
都是等待指定时间后自动苏醒,调用wait方法的当前线程会释放该同步监视器的锁定,可以不用notify或notifyAll方法把它唤醒。

notify()
唤醒在同步监视器上等待的单个线程,如果所有线程都在同步监视器上等待,则会选择唤醒其中一个线程,选择是任意性的,只有当前线程放弃对该同步监视器的锁定后,也就是使用wait方法后,才可以执行被唤醒的线程。

notifyAll()方法
唤醒在同步监视器上等待的所有的线程。只用当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程

案例:

package com.xiaomo.thread;

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

public class Account {

// 封装账户编号,账户余额两个Field
private String accountNo;
private double balance;

// 账户中是否已有存款的标志
private boolean flag = false;

// 显示定义Lock对象
private final Lock lock = new ReentrantLock();
// 获得指定Lock对象对应Condition
private final Condition cond = lock.newCondition();

// 定义锁对象
private final ReentrantLock relock = new ReentrantLock();

// 构造器
public Account() {

}

public Account(String accountNo, double balance) {
this.setAccountNo(accountNo);
this.setBalance(balance);
}

public int hashCode() {
return accountNo.hashCode();
}

// 下面两个方法根据accountNo来重写hashCode()和equals()方法
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == Account.class) {
Account target = (Account) obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}

// 提供一个线程安全的draw方法来完成取钱操作(同步方法)
public synchronized void draw(double drawAmount) {
// 账户余额大于取钱数目
if (balance >= drawAmount) {
// 吐出真钞
System.out.println(Thread.currentThread().getName() + "取钱成功!吐出真钞:"
+ drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 修改余额
balance -= drawAmount;
System.out.println("\t 余额为:" + balance);
} else {
System.out.println(Thread.currentThread().getName() + "取钱失败!余额不足!");
}
}

// 提供一个线程安全的draw方法来完成取钱操作(同步锁)
public void acquire(double drawAmount) {
// 加锁
relock.lock();
try {
if (balance >= drawAmount) {
// 吐出真钞
System.out.println(Thread.currentThread().getName()
+ "取钱成功!吐出真钞:" + drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 修改余额
balance -= drawAmount;
System.out.println("\t 余额为:" + balance);
} else {
System.out.println(Thread.currentThread().getName()
+ "取钱失败!余额不足!");
}
} finally {
// 修改完成,释放锁
relock.unlock();
}
}

// 同步方法的线程通信方式
public synchronized void get(double drawAmount) {
try {
// 如果flag为false,表明账户中还没有人存钱进去,取钱方法阻塞
if (!flag) {
this.wait();
} else {
if (balance >= drawAmount) {
// 执行取钱操作
System.out.println(Thread.currentThread().getName() + "取钱:"
+ drawAmount);
balance -= drawAmount;
System.out.println("账户余额为:" + balance);
// 将标志账户是否已有存款的标志设为false
flag = false;
// 唤醒其他线程
this.notifyAll();
} else {
System.out.println(Thread.currentThread().getName()
+ "取钱失败!余额不足!");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}


// 同步方法的线程通信方式
public synchronized void deposit(double drawAmount) {
try {
// 如果flag为true,表明账户中已有人存钱进去,存钱方法阻塞
if (flag) {
this.wait();
} else {
// 执行存款操作
System.out.println(Thread.currentThread().getName() + "存钱:"
+ drawAmount);
balance += drawAmount;
System.out.println("账户余额为:" + balance);
// 将表示账户是否已有存款的标志设为true
flag = true;
// 唤醒其他线程
this.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}

// 同步锁方式进行线程通信
public void getLock(double drawAmount) {
lock.lock();
try {
// 如果flag为true,表明账户中已有人存钱进去,存钱方法阻塞
if (!flag) {
cond.await();
} else {
if (balance >= drawAmount) {
// 执行取钱操作
System.out.println(Thread.currentThread().getName() + "取钱:"
+ drawAmount);
balance -= drawAmount;
System.out.println("账户余额为:" + balance);
// 将标志账户是否已有存款的标志设为false
flag = false;
// 唤醒其他线程
cond.signalAll();
} else {
System.out.println(Thread.currentThread().getName()
+ "取钱失败!余额不足!");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}


// 同步锁方式进行线程通信
public void depositLock(double drawAmount) {
lock.lock();
try {
// 如果flag为true,表明账户中已有人存钱进去,存钱方法阻塞
if (flag) {
cond.await();
} else {
// 执行存款操作
System.out.println(Thread.currentThread().getName() + "存钱:"
+ drawAmount);
balance += drawAmount;
System.out.println("账户余额为:" + balance);
// 将表示账户是否已有存款的标志设为true
flag = true;
// 唤醒其他线程
cond.signalAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public String getAccountNo() {
return accountNo;
}

public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}

public double getBalance() {
return balance;
}

public void setBalance(double balance) {
this.balance = balance;
}
}

出处:http://blog.csdn.net/cl05300629/article/details/13000609 作者:伫望碧落

分享到:
评论

相关推荐

    Java多线程小结

    Java中多线程的学习的自我小结,有多线程的意思,多线程常见的控制方法等内容

    java线程基本知识小结.doc

    java线程基本知识小结.doc java线程基本知识小结.doc

    java线程详解

    八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...

    Java线程类小结(附思维导图)

    NULL 博文链接:https://newjueqi.iteye.com/blog/400862

    java应用程序中使用线程

    3.1 Java线程 3.2 创建线程 3.3 使用线程的缺点 3.3.1 初始启动变慢 3.3.2 资源利用 3.3.2 资源利用 3.4 线程管理 3.5 共享资源的使用同步 3.5.1 同步方法和同步代码块的嵌套调用...

    JAVA多线程操作方法实用大全

    欧柏泰克教学小结:JAVA多线程操作方法实用大全

    Java线程安全问题小结_动力节点Java学院整理

    主要介绍了Java线程安全问题小结的相关资料,需要的朋友可以参考下

    JAVA实现线程的方法

    欧柏泰克课堂小结:JAVA实现线程的方法

    JAVA清华大学教程

    ◇本讲小结 ◇课后习题 ★ 第二讲 Java语言基础知识 ◇课前索引 ◇2.1 简单数据类型 ◇2.2 运算符和表达式 ◇2.3 控制语句 ◇2.4 数组 ◇2.5 字符串的处理 ◇本讲小结 ◇课后习题 ★ 第三讲 Java语言...

    JAVA 清华大学 教程

    ◇本讲小结 ◇课后习题 ★ 第二讲 Java语言基础知识 ◇课前索引 ◇2.1 简单数据类型 ◇2.2 运算符和表达式 ◇2.3 控制语句 ◇2.4 数组 ◇2.5 字符串的处理 ◇本讲小结 ◇课后习题 ★ 第三讲 Java语言...

    突破JAVA万人面试,懂多线程者得天下.zip

    目录网盘文件永久链接 01课程安排av 02什么是并发和并行av ...08线程创建小结av 09线程生命周期avi 10.线程安全问题什么是线程安全avi 11线程安全同题问题分析avi 12线程安全问题线程安全问题演示avi ...............

    清华大学JAVA教程

    ★ 第二讲 Java语言基础知识 ◇课前索引 ◇2.1 简单数据类型 ◇2.2 运算符和表达式 ◇2.3 控制语句 ◇2.4 数组 ◇2.5 字符串的处理 ◇本讲小结 ◇课后习题 ★ 第三讲 Java语言中的面向对象特性 ◇课前...

    Java编程语言详细教程

    ◇本讲小结 ◇课后习题 ★ 第二讲 Java语言基础知识 ◇课前索引 ◇2.1 简单数据类型 ◇2.2 运算符和表达式 ◇2.3 控制语句 ◇2.4 数组 ◇2.5 字符串的处理 ◇本讲小结 ◇课后习题 ★ 第三讲 Java语言...

    Java程序设计案例教程-第8章-多线程编程.pptx

    第4页 主要内容 8.1 Java线程模型 8.2 创建线程 8.3 同步与线程间通信 8.4 获取线程状态 8.5 本章小结 8.6 思考和练习 Java程序设计案例教程-第8章-多线程编程全文共36页,当前为第4页。 8.1 Java线程模型 Java对多...

    分享40个Java多线程问题小结

    多个线程共存于同一JVM进程里面,所以共用相同的内存空间,较之多进程,多线程之间的通信更轻量级,本文给大家分享40个Java多线程问题小结 的相关资料,需要的朋友可以参考下

    实验5 JAVA常用类.doc

    本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...

    Java基础知识点总结.docx

    Java数组与集合小结 305 递归 309 对象的序列化 310 Java两种线程类:Thread和Runnable 315 Java锁小结 321 java.util.concurrent.locks包下常用的类 326 NIO(New IO) 327 volatile详解 337 Java 8新特性 347 Java...

    java 创建线程的方法总结

    主要介绍了java 创建线程的方法总结的相关资料,需要的朋友可以参考下

    (超赞)JAVA精华之--深入JAVA API

    1.6 Java线程 1.7 Java 5.0多线程编程 1.8 Java Socket编程 1.9 Java的内存泄漏 1.10 抽象类与接口的区别 1.11 Java变量类型间的相互转换 2 JAVA与WEB 2.1 JMX规范 2.1.1 JMX概述 2.1.2 设备层(Instrumentation ...

Global site tag (gtag.js) - Google Analytics