线程相关知识点总结

1.线程的启动方式

开启主要有两种:继承Thread和实现cannable接口;

  • 继承Thread:
public class Practice {
	public static void main(String[] args) {
//	继承 Thread  任务:copy文件
		Copy c = new Copy();
		c.start();
		}
}
class Copy extends Thread{
	@Override
	public void run() {
		File filename = new File("a.txt");
		File copyname = new File("copy.txt");
		try {
			copyFile(filename,copyname );
			System.out.println("复制成功");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}		
	private void copyFile(File fileName,File copyName) throws Exception {
		FileInputStream fis = new FileInputStream(fileName);
		FileOutputStream fos = new FileOutputStream(copyName);
		int len = 0;
		byte[] byt= new byte[1024];
		while ((len=fis.read(byt))!=-1) {
			fos.write(byt, 0, len);
			fos.flush();			
		}
		fis.close();
		fos.close();		
	}
}
  • 实现cannable接口:
public class Practice {
	public static void main(String[] args) {
//	实现runnable 任务:输出任意范围字母
		Print p= new Print();
		Thread thread = new Thread(p);
		thread.start();
		}
}
class Print implements Runnable{
	@Override
	public void run() {
		int a = (int) (Math.random()*26+97);
		int b = (int) (Math.random()*26+97);
		if (a>=b) {
			for (int i = b; i <= a; i++) {
				System.out.print("实现Runable"+(char)i+"  ");
			}
		}else if (a<b) {
			for (int i = a; i <= b; i++) {
				System.out.print("实现Runable"+(char)i+"  ");
			}
		}
	}	
}
2.线程的生命周期

在这里插入图片描述

3.线程池
  • 线程池的开启:

Executors 工厂类来产生线程池。
构造方法
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()

 */
public class ThreadDemo01 {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		// 创建线程池
		ExecutorService pool = Executors.newFixedThreadPool(3);
		// 将线程放入到池中
		pool.submit(new MyRunnable());
		Future<Integer> future = pool.submit(new MyCallable());
		pool.submit(new Runnable() {			
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					System.out.println(Thread.currentThread().getName() + "线程池匿名内部类实现Runnable方式开启线程:" + i);
				}
			}
		});
		System.out.println("1~100的和为:" + future.get());		
		// 结束线程池
		pool.shutdown();
	}
}

class MyRunnable implements Runnable {
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(Thread.currentThread().getName() + "线程池实现Runnable方式开启线程:" + i);
		}
	}	
}

class MyCallable implements Callable<Integer> {
	@Override
	public Integer call() throws Exception {		
		int sum = 0;
		for (int i = 1; i <= 100; i++) {
			System.out.println(Thread.currentThread().getName() + "线程池实现Callable方式开启线程:" + i);
			sum += i;
		}
		return sum;
	}	
}
4.线程同步
5.线程通信:
  • 通过构造方法 A -> B A在启动之前传递给B
  • 通过实现Callable接口的方式 A -> B B在执行结束之后将数据回传给A
  • 利用接口回调方式传递数据
  • 利用同步锁串行实现数据传递
  • 利用等待唤醒机制
    下面主要解释下后三种方法:
    (1.)接口回调
    1.创建一个回调接口[电话号码],接口中书写方法 A->B
    方法的形参就是 B线程使用形参传递给A线程
    方法的返回值就是 A线程使用返回值传递给B线程
    2.A线程将这个回调接口通过构造方法传递给B线程
    3.B线程在使用这个接口,即接口回调
 public class Test {
	public static void main(String[] args) {
		BThread thread = new BThread("B", new ICallBack() {			
			@Override
			public String fun(int a, int b, String message) {
				int sum = a + b;
				System.out.println("收到了来自于B线程的消息: " + message);
				return sum + ":" + BThread.currentThread().getName();
			}
		});
		thread.start();		
	}
}

class AThread extends Thread {
	@Override
	public void run() {
	}
}
class BThread extends Thread {	
	private ICallBack cb;	
	public BThread() {}	
	public BThread(String name, ICallBack cb) {
		super(name);
		this.cb = cb;
	}
	public void setCb(ICallBack cb) {
		this.cb = cb;
	}
	public void run() {
		String result = cb.fun(10, 20, "我是线程B带过来两个整数数据");
		System.out.println("收到了来自于A线程的数据: " + result);
	}	
}
// 回调接口
interface ICallBack {
	String fun(int a, int b, String message);
}

(2.)利用同步锁串行实现数据传递

public class Test9 {
	public static void main(String[] args) {
		MyObject object =new MyObject();
//		三个线程共享一个锁对象
		MythreadA ma = new MythreadA(object);
		MythreadB mb = new MythreadB(object);
		MythreadC mc = new MythreadC(object);
		ma.start();
		mb.start();
		mc.start();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(object.getCount());
	}
}

class MythreadA extends Thread {
	private MyObject object;
	public void run() {
		object.methodA("A");
		System.out.println("ma执行完后count为"+object.getCount());
	};
	public MythreadA() {
	}
	public MythreadA(MyObject object) {
		this.object = object;
	}
	public Object getObject() {
		return object;
	}
	public void setObject(MyObject object) {
		this.object = object;
	}

}

class MythreadB extends Thread {
	private MyObject object;
	public void run() {
		object.methodB("B");
		System.out.println("mb执行完后count为"+object.getCount());
	};
	public MythreadB() {
	}
	public MythreadB(MyObject object) {
		this.object = object;
	}
	public Object getObject() {
		return object;
	}
	public void setObject(MyObject object) {
		this.object = object;
	}
}

class MythreadC extends Thread {
	private MyObject object;
	public void run() {
		object.methodC("C");
		System.out.println("mc执行完后count为"+object.getCount());
	};
	public MythreadC() {
	}
	public MythreadC(MyObject object) {
		this.object = object;
	}
	public Object getObject() {
		return object;
	}
	public void setObject(MyObject object) {
		this.object = object;
	}
}
//自定义锁对象
class MyObject {
	private String count = "";
	public MyObject() {

	}
//同步方法的锁对象是this(为调用者),由于调用的对象为同一对象object,因此锁对象一样。
	public synchronized void methodA(String message) {
		System.out.println(message);
		count += message;
	}

	public synchronized void methodB(String message) {
		System.out.println(message);
		count += message;
	}

	public synchronized void methodC(String message) {
		System.out.println(message);
		count += message;
	}

	public MyObject(String count) {
		this.count = count;
	}
	public String getCount() {
		return count;
	}
	public void setCount(String count) {
		this.count = count;
	}
	@Override
	public String toString() {
		return "Object [count=" + count + "]";
	}	
}

(3.)利用等待唤醒机制
wait(),notify(),notifyll()
生产者消费者模型:

//共享资源
public class Toy {
	private String name; // 玩具名称
	private int num; // 玩具数量
	private boolean flag; // 是否有玩具, 有表示true,没有表示false
	public Toy() {
		super();
	}
	public Toy(String name, int num, boolean flag) {
		super();
		this.name = name;
		this.num = num;
		this.flag = flag;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public boolean isFlag() {
		return flag;
	}
	public void setFlag(boolean flag) {
		this.flag = flag;
	}
	@Override
	public String toString() {
		return "Toy [name=" + name + ", num=" + num + ", flag=" + flag + "]";
	}
}
//消费者线程
public class GetThread extends Thread {
	private Toy t;
	public GetThread() {
	}
	public GetThread(Toy t) {
		this.setT(t);
	}	
	@Override
	public void run() {		
		while (true) {
			synchronized (t) {
				// 先判断是否有玩具
				if (!t.isFlag()) {
					// 没有,就等待生产者生产
					try {
						t.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}				
				// 有,就消费
				String toyName = t.getName();
				int toyNum = t.getNum();
				System.out.println(toyName + "|" + toyNum);
				// 消费一次数量减一
				t.setNum(--toyNum);				
				// 消费完毕之后,就通知生产者生产
				if (toyNum <= 0) {
					// 设置标志位,说明没有玩具了
					t.setFlag(false);
					// 消费完毕之后,就通知生产者生产
					t.notify();
				}
			}
		}		
	}
	public Toy getT() {
		return t;
	}
	public void setT(Toy t) {
		this.t = t;
	}		
}
//生产者线程
public class SetThread extends Thread {
	private Toy t;
	private int i;
	public SetThread() {
		super();
	}
	public SetThread(Toy t) {
		super();
		this.t = t;
	}	
	@Override
	public void run() {
		while (true) {
			synchronized (t) {
				// 先判断是否有玩具
				if (t.isFlag()) {
					// 就等待消费者消费
					try {
						t.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}				
				// 没有,就生产
				if (i % 2 == 0) {
					t.setName("Hello Kitty");
					t.setNum(10);
				} else {
					t.setName("King");
					t.setNum(5);
				}
				i++;				
				// 设置标志位,表示目前已经有数据了
				t.setFlag(true);				
				// 生产完毕之后通知消费者消费  nofity
				t.notify();
			}
		}		
	}
	public Toy getT() {
		return t;
	}
	public void setT(Toy t) {
		this.t = t;
	}	
}
//主线程
public class ThreadDemo01 {
	public static void main(String[] args) {
		Toy t = new Toy();		
		SetThread st = new SetThread(t);
		GetThread gt = new GetThread(t);		
		st.start();
		gt.start();
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值