线程的基本概念:
线程:同一程序的不同线路,线程是cpu的最小调度单位,线程之间的数据是可共享的。
进程:一个正在运行中的程序就是一个进程,是操作系统中的最小调度单位,进程之间的数据是不可以共享的。
线程的三个要素:CPU,CODE,DATA。
线程时候从进程中派生过来的。
多任务,多线程,多用户的操作系统。
package threadDemo1;
/*
class MyThread extends Thread{
@Override
public void run() {
for (int j = 0; j <100 ; j++) {
System.out.println(Thread.currentThread().getName()+" j="+j);
try{
Thread.sleep(500);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}*/
class MyThread implements Runnable{
@Override
public void run() {
for (int j = 0; j <100 ; j++) {
System.out.println(Thread.currentThread().getName()+" j="+j);
try{
Thread.sleep(500);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
public class ThreadDemo1 {
//主方法就是一个主线程
public static void main(String[] args) {
MyThread my=new MyThread();
Thread th=new Thread(my);
th.start();
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+" i="+i);
try{
Thread.sleep(500);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
这个是以两种方式实现的线程
1.通过继承Thread
2.实现Runnable接口
1. Thread th=new Thread();
Thread th=new Thread(String);
2.Thread th=new Thread(Runnable run);
3.Thread th=new Thread(Runnable run,String);
join方法:
package threadDemo3;
class Son implements Runnable{
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
if("大儿子".equals(Thread.currentThread().getName())){
System.out.println("我是大儿子,我正在买酱油");
}
else{
System.out.println("我是小儿子,我在买辣椒");
}
try{
Thread.sleep(500);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
public static class Mother {
public static void main(String[] args) {
System.out.println("今天中午给你们大盘鸡");
System.out.println("家里没有酱油和辣椒了..");
Son son = new Son();
Thread bigSon = new Thread(son, "大儿子");
Thread smallSon=new Thread(son,"小儿子");
bigSon.start();
smallSon.start();
try{
bigSon.join();
smallSon.join();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
同步代码块:
Java实现线程的同步,通过给对象上锁的机制来完成的
每个对象都有一把锁
同步代码块:synchronized(obj){ }
当线程要执行同步代码块,要先检查当前线程是否拥有obj这个对象的锁,如果有,则进入代码块
如果没有,当前线程进入到锁池状态等待其他线程释放锁,一旦释放,当前线程有机会获得对象的锁,进入同步代码块
当线程执行完同步代码块,会主动释放该对象的锁,以保障其他线程有机会执行这个代码块
同步方法:
修饰符 synchronized 返回类型 方法名字(参数列表)
{
}
当线程要执行同步代码块,要先检查当前线程是否拥有执行当前方法的哪个对象的锁,如果有,则进入代码块
如果没有,当前线程进入到锁池状态等待其他线程释放锁,一旦释放,当前线程有机会获得对象的锁,进入同步代码块
当线程执行完同步代码块,会主动释放该对象的锁,以保障其他线程有机会执行这个代码块
Wait 和Notify
package threadDemo4;
class SleeppingRoom implements Runnable{
Object tolite=new Object();
@Override
public void run() {
synchronized (tolite){
if("小张".equals(Thread.currentThread().getName())){
brushteeh();
tolite.notify();//唤醒小李线程可以使用卫生间
try{
tolite.wait();//释放卫生间当前的锁,使自己进入锁池状态
}
catch(Exception ex){
ex.printStackTrace();
}
xuxu();
tolite.notify();
}
else{
brushteeh();
tolite.notify();//唤醒小张线程可以使用卫生间
try{
tolite.wait();//释放卫生间当前的锁,使自己进入锁池状态
}
catch(Exception ex){
ex.printStackTrace();
}
xuxu();
}
}
}
//刷牙
public void brushteeh(){
System.out.println(Thread.currentThread().getName()+":正在刷牙...");
try{
Thread.sleep(500);
}
catch(Exception ex){
ex.printStackTrace();
}
}
//小便
public void xuxu(){
System.out.println(Thread.currentThread().getName()+":正在尿尿...");
try{
Thread.sleep(500);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
public class SleeppingRoomDemo {
public static void main(String[] args) {
SleeppingRoom room=new SleeppingRoom();
Thread xiaoZhang=new Thread(room,"小张");
Thread xiaoLi=new Thread(room,"小李");
xiaoZhang.start();
try{
Thread.sleep(300);
}
catch(Exception ex){
ex.printStackTrace();
}
xiaoLi.start();
}
}
Callable接口:
class MyCallable implements Callable<Long>{
private int num;
MyCallable(int num){
this.num=num;
}
@Override
public Long call() throws Exception {
Long result=0L;
while(true){
if(num>100000){
break;
}
result+=num;
num+=2;
}
return result;
}
}
public class CallableDemo {
public static void main(String[] args) throws Exception{
MyCallable even=new MyCallable(0);
MyCallable odd=new MyCallable(1);
ExecutorService threadPool= Executors.newFixedThreadPool(2);
Future<Long> evenResult =threadPool.submit(even);
Future<Long> oddResult =threadPool.submit(odd);
threadPool.shutdown();
System.out.println("偶数之和:"+evenResult.get());
System.out.println("奇数之和:"+oddResult.get());
}
}
结果: