Java 线程多线程编程1---基础

1、线程的基本概念


例子:


分析:


2、线程的创建和启动


第一种线程的创建:

    定义一个线程类来实现Runner接口

例子:

package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {
	public static void main(String[] args) {
		Runner1 runner1  = new Runner1();
		Thread myThread  = new Thread(runner1);
		myThread.start();//这行注释掉的话,线程就不会执行。
		for(int i=0;i<100;i++) {
			System.out.println("Main Thread:-----" + i);
		}
	}
}
class Runner1 implements Runnable{
	public void  run() {
		for(int i = 0;i<100;i++) {
			System.out.println("Runner1:" + i);
		}
	}
}

运行结果:


我们会发现,主线程,和子线程是交替执行的。

但是呢,要注意:

但是若是直接调用run方法,是方法调用,两者之间天壤之别,只有执行完成一个才会去执行另一个。


package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {
	public static void main(String[] args) {
		Runner1 runner1  = new Runner1();
		//Thread myThread  = new Thread(runner1);
		runner1.run();
		//myThread.start();//这行注释掉的话,线程就不会执行。
		for(int i=0;i<100;i++) {
			System.out.println("Main Thread:-----" + i);
		}
	}
}
class Runner1 implements Runnable{
	public void  run() {
		for(int i = 0;i<100;i++) {
			System.out.println("Runner1:" + i);
		}
	}
}
证明如下:


第二种线程的创建:

定义一个Thread的子类并重写其run方法。

例子:

package com.zhj.www;
import java.lang.Thread;
public class TestThread1 {
	public static void main(String[] args) {
		
		MyThread myThread  = new MyThread();
		myThread.start();
		for(int i=0;i<100;i++) {
			System.out.println("Main Thread:-----" + i);
		}
	}
}
class MyThread extends Thread{
	public void  run() {
		for(int i = 0;i<100;i++) {
			System.out.println("Runner1:" + i);
		}
	}
}

此时,已经新建一个MyThread类继承自Thread类,所以就不用new一个Thread 的对象出来了,而只需要new一个MyThread的子对象。然后调用其start()方法。

执行结果:


我们发现和第一种创建线程的结果是一样的,也是交替执行。但是两个线程分得到的时间片并不一定是相同的。

两个方式有什么区别呢?继承Thread类的方式(第二种方式)比较死,只能从一个类继承,第一种方式呢?比较灵活实现接口,还可以从其他类继承。只要能实现接口,就不要从Thread类继承。

线程状态转换:




1、sleep方法:

package com.zhj.www;

import java.util.*;

public class TestInterrupt {
	public static void main(String[] args) {
		MyThread thread = new MyThread();
		thread.start();
		try {
			Thread.sleep(10000);//主线程睡眠
		}catch (InterruptedException e) {}
		//thread.interrupt();//睡着的时候打断,太粗暴了//为什么不用它呢?
		thread.flag = false;
	}
}

class MyThread extends Thread{
	boolean flag = true;
	public void run() {
		while(flag) {
			System.out.println("==="+new Date()+"===");
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}
}

运行结果:


2、join方法:


栗子:

package com.zhj.www;

public class TestJoin {
	public static void main(String[] args) {
		MyThread2 t1 = new MyThread2("abcdef");
		t1.start();
		try {
			t1.join();//合共
		}catch (InterruptedException e) {}
		for(int i = 1;i<=10;i++) {
			System.out.println("I am main thread");
		}
	}
}
class MyThread2 extends Thread{
	public MyThread2(String s) {
		super(s);
	}
	public void run() {
		for(int i = 0; i<=10;i++) {
			System.out.println("I am "+ getName()+" (i:)"+i);
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}
}

运行结果:



3、yield方法:


package com.zhj.www;

import java.util.*;

public class TestYield {
	public static void main(String[] args) {
		MyThread3 t1 = new MyThread3("t1");
		MyThread3 t2  = new MyThread3("t2");
		t1.start();
		t2.start();
	}
}

class MyThread3 extends Thread{
	MyThread3(String s) {
		super(s);
	}
	public void run() {
		for (int i = 1; i <= 100; i++) {
			System.out.println(getName()+": "+i);
			if(i%10 == 0) {
				yield();
			}
		}
	}
}

运行结果:

t1到10的倍数切换t2,t2到10的倍数切换t1;


上例子:

package com.zhj.www;

public class TestPriority {
	public static void main(String[] args) {
		Thread t1 = new Thread(new T1());
		Thread t2 = new Thread(new T2());
		t1.setPriority(Thread.NORM_PRIORITY+3);//t1得到的执行时间长
		t1.start();
		t2.start();
	}
}
class T1 implements Runnable{
	public void run() {
		for(int i =0;i< 100;i++) {
			System.out.println("T1: "+ i);
		}
	}
}
class T2 implements Runnable{
	public void run() {
		for(int i =0;i< 100;i++) {
			System.out.println("-------T2: "+ i);
		}
	}
}
运行一下:

可以发现:t1比t2运行的时间长。

--------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------

额外的栗子:

--------------------------------------------------------------------------------------

TestThread2.java

package com.zhj.www;

public class TestThread2 {
	public static void main(String[] args) {
		Runner2 r = new Runner2();
		Thread t1 = new Thread(r);
		Thread t2 = new Thread(r);
		t1.start();
		t2.start();
		
	}
}

class Runner2 implements Runnable{
	public void run() {
		for(int i = 0; i <= 30; i++) {
			System.out.println("No: "+ i);
		}
	}
}

运行一下:

TestThread3.java

package com.zhj.www;

public class TestThread3 {
	public static void main(String[] args) {
		Runner3  runner3 = new Runner3();
		Thread thread = new Thread(runner3);
		thread.start();
	}
}
class Runner3 implements Runnable {
	public void run() {
		for(int i = 0; i<30;i++) {
			if(i%10 == 0 && i != 0) {
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {}
			}
			System.out.println("No. " + i);
		}
	}
}

当i 是 10的倍数时,会睡眠2s。

运行结果:

TestThread4.java

package com.zhj.www;

public class TestThread4 {
	public static void main(String[] args) {
		Runner4 r  = new Runner4();
		Thread t = new Thread(r);
		t.start();
		for(int i = 0; i< 100000 ; i++) {
			if(i%10000 == 0 & i>0) {
				System.out.println("in thread main i =" + i);
			}	
		}
		System.out.println("Thread mian is over");
		r.shutDown();
	}
}

class Runner4 implements Runnable{
	private boolean flag = true;
	public void run() {
		int i = 0;
		while(flag == true) {
			System.out.println(" " + i++);
		}
	}
	
	public void shutDown() {
		flag = false;
	}
}

主要:怎么让一个正常执行的线程停止。

run方法结束,线程就结束。

运行结果:


TestThread5.java(关于join方法)

package com.zhj.www;

public class TestThread5 {
	public static void main(String[] args) {
		Runner5 r = new Runner5();
		Thread thread = new Thread(r);
		thread.start();
		try {
			thread.join();
		}catch (InterruptedException e) {}
		for(int i = 0; i<50;i++) {
			System.out.println("主线程:"+ i);
		}
	}
}
class Runner5 implements Runnable{
	public void run(){
		for(int i= 0 ;i<50;i++) {
			System.out.println("SubThread: " + i);
		}
	}
}
运行结果:

TestThread6.java

package com.zhj.www;

public class TestThread6 {
	public static void main(String[] args) {
		Thread thread = new Runner6();
		thread.start();
		
		for(int i = 0; i<50 ;i++) {
			System.out.println("MainThread: "+ i);
		}
	}
}

class Runner6 extends Thread{
	public void run() {
		System.out.println(Thread.currentThread().isAlive());
		for(int i = 0;i<50;i++) {
			System.out.println("SubThread: " + i);
		}
	}
}


----------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------

线程同步



自身是一个线程类。

分析内存:


分析完内存,我们运行一下:

package com.zhj.www;

public class TestSync implements Runnable{
	Timer timer  =new Timer();
	public static void main(String[] args) {
		TestSync testSync = new TestSync();
		Thread t1 = new Thread(testSync);
		Thread t2 = new Thread(testSync);
		t1.setName("t1");
		t2.setName("t2");
		t1.start();
		t2.start();
	}
	
	public void run() {
		timer.add(Thread.currentThread().getName());
	}
}

class Timer{
	private static int num = 0;
	public void add(String name ) {
		num++;
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {}
		System.out.println(name+",你是第"+num+"个使用timer的线程");
	}
}

运行一下:

结果为什么是这样呢?感觉哪里不对。

线程在执行这个方法时,被另一个线程打断了。写sleep,是为了

放大这个效果。

怎么解决呢?

在执行的时候,锁定当前对象。一个执行进入到锁住区域时,另一个

线程不可打扰。

如下:

public void add(String name ) {
		synchronized (this) {
			num++;
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {}
			System.out.println(name+",你是第"+num+"个使用timer的线程");
		}
	}

互斥锁。

另外简便的写法:

public  synchronized void add(String name ) {
		//synchronized (this) {
			num++;
			try {
				Thread.sleep(1);
			} catch (InterruptedException e) {}
			System.out.println(name+",你是第"+num+"个使用timer的线程");
		//}
	}

执行这个方法时,锁住当前对象。

睡着的时候,依然抱着这把锁,其他的人如果要执行这个方法必须等他执行完这个方法。



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值