/*
线程的状态:
新建
可运行
运行
阻塞
终止
实现线程的两种方法:1、继承thread类。2、实现Runnable接口。
Runnable:如果不用修改线程(除了run()方法外)其他方法,则用实现Runnable接口的方法。
多个线程共享同一个变量,操纵同一对象。
实现java.lang.Runnable接口,必须实现run()方法。
当创建并运行线程时,实现类的实例作为参数传递给Thread类的构造函数,然后调用Thread类的start()方法执行线程
Thread:在多线程时,独立享有变量。
创建java.lang.thread类的子类,并覆盖Thread类的run()方法。
子类通过调用start()方法执行线程
线程的调度(由时间片轮转来实现线程之间的转换)
1、一个线程对象的start方法只能被执行一次
2、一个时刻只是一个线程在运行
3、休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
4、线程是抢占式的:优先级
5、运行到不再是可运行的,或另一个更高优先级的线程成为可运行
6、所有可运行线程按优先级保存在缓冲池中
7、优先权(priority),MAX_PRIORITY=10、NORM_PRIORITY=5、MIN_PRIORITY=1
8、加入到某个线程(join),一个线程可以在其它线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。
如果某个线程thread在另一个线程上调用thread.join(),此线程将被挂起,直到目标线程thread结束才恢复。
线程的同步:锁定任何对象所占用的内存,试的同一时刻只能有一个线程在使用它。通过synchronized关键字来实现的。
线程的同步有两种方式:
1、同步块(同步代码段):用加锁和解锁来控制当前线程数,并需要传入对象(如果传入的是this,则能和同步方法同步)。
synchronized(syncObject){//在对象syncObject上加锁,同一时刻只能有一个线程访问}
2、同步方法:用加锁和解锁来控制当前线程数,并用this监视器监视。
在当前对象上加锁,同一时刻只能有一个线程访问当前对象的此方法(保证该方法中的所有指令同步进行,中间不会被打断)
在对象锁释放之前,该对象上其他同步方法也不能被访问
当我们同步的是静态方法是,所用的该类所对应的class方法。
同步的死锁: 例.当线程1,进入同步块A时,线程2,进入同步块B,而此时线程1要在同步块A中访问同步块B,线程2要在同步块B中访问同步块A,因线程1,进入同步块A时,同步块A加锁(同步块B同此),所以线程1需要等待同步块B解锁(线程2亦然),彼此都不能完成,形成死锁。
其中resume()和suspend()方法,容易造成线程的死锁,不建议使用。
wait、notify、notifyall 必须在同步方法或块中被调用eg.
每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,大的等待队列是空的。
在当前线程锁住对象的锁后,去调用该对象的wait方法。
当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可运行的线程。
当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。
wait和notify主要用于producer-consumer这种关系中。
注:应该作用于同一个对象!!!
线程的终止
1、设置一个flag变量
2、结合interrupt()方法
注: 1、线程是通过start()方法来调用的,调用线程类中的run()方法,是不能启动线程的,那只是调用了run()方法而已。
2、一个线程重复调用是非法的。
3、优先权高,不代表就先运行,只是抢占cpu时间的几率更高。
*/
//实例一----Thread和Runnable
/*
实现线程的两种方法:1、继承thread类。2、实现Runnable接口。
Runnable:实现java.lang.Runnable接口,必须实现run()方法。
当创建并运行线程时,实现类的实例作为参数传递给Thread类的构造函数,然后调用Thread类的start()方法执行线程
Thread:创建java.lang.thread类的子类,并覆盖Thread类的run()方法。
子类通过调用start()方法执行线程
*/
//Thread例
public class PrimeThread extends Thread {
public PrimeThread(String name) {
setName(name);
}
@Override
public void run() {
for(int i=0;i<20;i++)
{
System.out.println(getName()+" NO."+i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
Thread thread1=new PrimeThread("geass");
Thread thread2=new PrimeThread("holic");
Thread thread3=new PrimeThread("clannad");
Thread thread4=new PrimeThread("code");
thread4.setName("liar"); //将线程的名字改为liar
//启动线程
thread1.start();
System.out.println("--------------------Thread1:geass started");
thread2.start();
System.out.println("--------------------Thread2:holic started");
thread3.start();
System.out.println("--------------------Thread3:clannad started");
thread4.start();
System.out.println("--------------------Thread4:liar started");
}
}
//Runnable例
public class PrimeRunnable implements Runnable{
private String name;
public PrimeRunnable(String name) {
this.name = name;
}
public void run() {
for(int i=0;i<20;i++)
{
System.out.println(name+" NO."+i);
}
}
}
public class RunnableTest {
public static void main(String[] args) {
Runnable run1=new PrimeRunnable("adieu");
Runnable run2=new PrimeRunnable("antique");
Runnable run3=new PrimeRunnable("highness");
Runnable run4=new PrimeRunnable("lord");
new Thread(run1).start();
System.out.println("--------------------Thread:adieu started");
new Thread(run2).start();
System.out.println("--------------------Thread:antique started");
new Thread(run3).start();
System.out.println("--------------------Thread:highness started");
new Thread(run4).start();
System.out.println("--------------------Thread:lord started");
}
}
//实例二----Thread和Runnable的区别
/*
*/
//
public class DifThread extends Thread{
private int i;
public DifThread(String name) {
setName(name);
}
public int getI() {
return i;
}
@Override
public void run() {
for(int j=0;j<5;j++){
i+=j;
System.out.println(getName()+" NO."+i);
}
}
}
public class DifThreadTest {
public static void main(String[] args) {
Thread t1=new DifThread("geass");
t1.start();
t1.start(); //会抛出异常,要采用新的实例!!!
//Thread t2=new DifThread("holic");
//t2.start();
}
}
//
public class DifRunnable implements Runnable{
private String name;
private int i;
public DifRunnable(String name) {
this.name = name;
}
public void run() {
for(int j=0;j<5;j++)
{
i+=j;
System.out.println(name+" NO."+i);
}
}
}
public class DifRunnableTest {
public static void main(String[] args) {
Runnable r1=new DifRunnable("adieu");
//直接调用
new Thread(r1).start();
new Thread(r1).start();
}
}
//实例三----进程的优先级
/*
线程是抢占式的:优先级
运行到不再是可运行的,或另一个更高优先级的线程成为可运行
所有可运行线程按优先级保存在缓冲池中
优先权(priority),MAX_PRIORITY=10、NORM_PRIORITY=5、MIN_PRIORITY=1
*/
//例1
class MaxThread extends Thread{
public MaxThread(String name) {
setName(name);
}
@Override
public void run() {
//setPriority(Thread.MAX_PRIORITY);
for(int i=0;i<10;i++){
System.out.println(getName()+"是高优先级"+10);
}
}
}
class NorThread extends Thread{
public NorThread(String name) {
setName(name);
}
@Override
public void run() {
//setPriority(Thread.NORM_PRIORITY);
for(int i=0;i<10;i++){
System.out.println(getName()+"是中优先级"+5);
}
}
}
public class PriorityTest {
public static void main(String[] args) {
Thread t1=new NorThread("geass");
Thread t2=new MaxThread("holic");
t1.setPriority(Thread.NORM_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
//例2
class PrioThread extends Thread{
public PrioThread(String name) {
setName(name);
}
@Override
public void run() {
System.out.println("当前进程名为:"+currentThread().getName()+",优先级为:"+currentThread().getPriority());
}
}
public class TestPriority {
public static void main(String[] args) {
System.out.println("线程名\t优先级");
Thread current=Thread.currentThread();
System.out.println(current.getName()+"\t");
System.out.println(current.getPriority()+"\t");
Thread t1=new PrioThread("geass");
Thread t2=new PrioThread("holic");
Thread t3=new PrioThread("adieu");
t2.setPriority(Thread.MAX_PRIORITY);
t1.setPriority(Thread.MIN_PRIORITY);
t3.setPriority(Thread.NORM_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
//实例四----进程的join
/*
加入到某个线程(join),一个线程可以在其它线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。
如果某个线程thread在另一个线程上调用thread.join(),此线程将被挂起,直到目标线程thread结束才恢复。
*/
//
public class JoinTest {
public static void main(String[] args) {
MyRunner r=new MyRunner();
MyRunner1 r1=new MyRunner1();
Thread t=new Thread(r);
Thread t1=new Thread(r1);
t.start();
try{
t.join(); //当t新城结束,t1线程才能恢复
}catch(Exception ex){
ex.printStackTrace();
}
t1.start();
try{
t1.join();
}catch(Exception ex){
ex.printStackTrace();
}
for(int i=0;i<200;i++){
System.out.println("Main Thread: "+i);
}
}
}
class MyRunner implements Runnable{
public void run(){
for(int i=0;i<200;i++){
System.out.println("Sub Thread: "+i);
}
}
}
class MyRunner1 implements Runnable{
public void run(){
for(int i=0;i<200;i++){
System.out.println("Thread: "+i);
}
}
}
//实例五----进程的sleep
/*
休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
*/
//
public class SleepTest {
public static void main(String[] args) {
SleepThread st1=new SleepThread("geass");
SThread st2=new SThread("holic");
st1.start();
st2.start();
}
class SleepThread extends Thread{
public SleepThread(String name) {
super(name);
}
@Override
public void run() {
try{
Thread.sleep(1000);
}catch(Exception ex){
ex.printStackTrace();
}
for(int i=0;i<200;i++){
System.out.println("线程名为:"+currentThread().getName()+", 线程号为:"+i);
}
}
}
class SThread extends Thread{
public SThread(String name) {
super(name);
}
@Override
public void run() {
for(int i=0;i<200;i++){
System.out.println("线程名为:"+currentThread().getName()+", 线程号为:"+i);
}
}
}
//实例六----进程的synchronized
/*
休眠,使线程停止执行一段时间,该时间由自定的毫秒数决定。
sleep方法是静态方法,它只是暂停当前执行中的线程,因此不能使用sleep方法来暂停其他线程的执行。
*/
//
public class BankAccount {
private int balance = 100;
public int getbalance() {
return balance;
}
public void withdraw(int amount){
balance-=amount;
}
}
//
public class WifeHusband implements Runnable {
private BankAccount account = new BankAccount();
public void run() {
while (account.getbalance() > 0) {
makeWithdraw(10);
if (account.getbalance() < 0) {
System.out.println("透支");
}
}
}
//方式一、同步方法
/* synchronized private void makeWithdraw(int amount) {
if (account.getbalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " is about to eithdraw");
try {
System.out.println(Thread.currentThread().getName() + " is going to sleep");
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " wake up");
account.withdraw(amount);
System.out.println(Thread.currentThread().getName() + " completes the withdraw");
} else {
System.out.println("Sorry,not enough for" + Thread.currentThread().getName());
}
}*/
//方式二、同步块
private void makeWithdraw(int amount) {
synchronized (this) {
if (account.getbalance() >= amount) {
System.out.println(Thread.currentThread().getName() + " is about to eithdraw");
try {
System.out.println(Thread.currentThread().getName() + " is going to sleep");
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " wake up");
account.withdraw(amount);
} else {
System.out.println("Sorry,not enough for " + Thread.currentThread().getName());
}
}
System.out.println(Thread.currentThread().getName() + " completes the withdraw");
}
public static void main(String[] args){
WifeHusband wh=new WifeHusband();
Thread wife = new Thread(wh);
Thread husband=new Thread(wh);
wife.setName("Jeffer");
husband.setName("Smith");
wife.start();
husband.start();
}
}