线程
来源:互联网 发布:import java.util. 编辑:程序博客网 时间:2024/06/05 11:04
/** * 创建并启动一个线程的方法 * 1) 实现接口的方式 * 1) 写一个具体类, 实现Runnable接口, 并实现其中的run方法,这个run方法就是线程的入口方法 * 2) 创建这个类的对象, 并以这个对象为实参, 创建Thread类的对象 * 3) 调用Thread对象的start()方法 启动线程 * */
/** * 多线程打印偶数,奇数,体会多线程的交替执行 * 线程的执行,抢占式 */public class ThreadTest { public static void main(String[] args) { //利用一个Runnable引用可以创建多个线程,只不过这几个线程共用一个run方法 //但是属于不同的线程,线程创建好的标志,有了栈 //多态 Runnable r = new PrintEven(); Thread t1 = new Thread(r); t1.setName("子线程1"); t1.start(); Thread t2 = new Thread(r); t2.setName("子线程2"); t2.start(); Runnable r2 = new PrintOdd(); Thread tt = new Thread(r2); tt.setName("子线程A"); tt.start(); }}//子线程打印偶数0~100class PrintEven implements Runnable{ private int i ; @Override public void run() { /* * 该线程要做的事,打印0~100的所有偶数 */ for(i = 0; i < 100; i += 2) { System.out.println(Thread.currentThread().getName() + ":" + i); } }}//子线程打印奇数0~100class PrintOdd implements Runnable{ private int i ; @Override public void run() { /* * 该线程要做的事情 */ for(i = 1; i < 100; i += 2) { System.out.println(Thread.currentThread().getName() + ":" + i); } }}
/** * 创建线程的第二种方式: * 继承的方式 * 1) 写一个具体类继承自Thread, 重写run方法, 这个run方法是真的入口 * 2) 创建具体类对象, 相当于创建了Thread对象 * 3) 调用Thread对象的.start() */class TestThread extends Thread { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(currentThread().getName() + " : " + i); } }}public class ThreadTest { public static void main(String[] args) { //自定义子线程 new TestThread().start(); //main线程 for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } }}
/** * 1.在main方法中创建并启动一个线程,线程循环随机打印100以内的整数,直到主线程从键盘读取了"Q"命令 * */import java.util.Scanner;public class GetRandomNumTest { public static void main(String[] args) { //创建线程 //利用实现Runnable接口创建线程本质还是创建Thread对象,(利用Runnable引用创建对象) /* * public Thread(Runnable target) { * init(null, target, "Thread-" + nextThreadNum(), 0); * } */ //多态 Runnable r = new GetRandomNum(); Thread t = new Thread(r); //开启线程 t.start(); //创建输入流从键盘获取信息 Scanner sc = null; try { sc = new Scanner(System.in); while(sc.hasNext()) { String str = sc.nextLine(); //不区分大小写 if(str.equalsIgnoreCase("Q")) { ((GetRandomNum)r).setStopflag(true); break; } } } catch (Exception e) { e.printStackTrace(); } finally { //对于Scanner对象关流不需要处理异常 sc.close(); } }}/* * 线程循环随机打印100以内的整数,直到主线程从键盘读取"Q" */class GetRandomNum implements Runnable { private boolean stopflag = false; public boolean isStopflag() { return stopflag; } public void setStopflag(boolean stopflag) { this.stopflag = stopflag; } @Override public void run() { /* * 因为线程要循环随机打印100以内的整数,直到主线程从键盘获取"Q" * 因此并不知道线程体中要循环多少次,要设置无限循环 * 同时因为要从外界来终止循环,所以要设置一个控制循环的布尔变量,当外界条件满足是修改布尔变量值,使得循环终止 */ while(!stopflag) { //打印当前线程名字和生成的随机整数 System.out.println(Thread.currentThread().getName() + ":" + (int)(Math.random() * 100)); } }}
import java.io.BufferedReader;import java.io.InputStreamReader;/** * 2.在main方法中启动两个线程。第一个线程循环随机打印100以内的整数,直到第二个线程从键盘读取了"Q"命令 * 将线程将要执行的任务放在线程体中 */public class GetRandomNumTest2 { public static void main(String[] args) { Runnable r = new GetRandomNumber(); Thread t = new Thread(r); Runnable r1 = new KeyListener((GetRandomNumber)r); Thread t1 = new Thread(r1); t.start(); t1.start(); }}class GetRandomNumber implements Runnable { private boolean stopflag = false; public boolean isStopflag() { return stopflag; } public void setStopflag(boolean stopflag) { this.stopflag = stopflag; } @Override public void run() { while(!stopflag) { int randomNum = (int)(Math.random() * 100); System.out.println(Thread.currentThread().getName() + " " + randomNum); } }}/* * 再设置一个线程控制循环结束,通过不断的监听键盘数据,进行判断,然后对循环进行控制 */class KeyListener implements Runnable { private GetRandomNumber getRandomNumber; public KeyListener(GetRandomNumber getRandomNumber) { this.getRandomNumber = getRandomNumber; } @Override public void run() { //设置输入流,从键盘获取信息,然后判断,对循环进行控制 InputStreamReader isr = null; BufferedReader bfr = null; try { isr = new InputStreamReader(System.in); bfr = new BufferedReader(isr); //方法2 String string = bfr.readLine(); while(true) { if(string.equalsIgnoreCase("Q")) { getRandomNumber.setStopflag(true); break; } string = bfr.readLine(); } /*方法1 //从键盘获取信息 String string = bfr.readLine(); //若不是q继续获取 while(!string.equalsIgnoreCase("Q")) { string = bfr.readLine(); } getRandomNumber.setStopflag(true); */ } catch (Exception e) { e.printStackTrace(); } finally { try { bfr.close(); } catch (Exception e2) { e2.printStackTrace(); } } }}
import java.util.ArrayList;import java.util.List;/** * 1.编写程序,在main中创建一个线程。线程每隔一定时间(200ms以内的随机时间)产生一个0~100之间的随机整数 * 打印后将该整数放到集合中,共产生100个整数,全部产生后,睡眠30秒,然后将集合内容打印输出 * 在main线程中,唤醒上述睡眠的线程,使其尽快打印集合内容 * * 首先要先构建目标线程类,在线程体中实现线程需要做的事情。 * 然后利用main线程唤醒 *实现精准控制,boolean变量 */public class GetDataTest { public static void main(String[] args) { //创建获取整数的线程 Runnable r = new GetData(); Thread t = new Thread(r); t.start(); /* //在main中实现精准控制打断 while(!((GetData)r).isFlag()) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } //当flag为true时,while循环结束执行下面语句,下面这个语句打断睡觉 t.interrupt(); */ //利用另一个线程做打断的工作 Runnable r1 = new Keylisten((GetData)r, t); Thread t1 = new Thread(r1); t1.start(); }}/* * 线程的任务,将这些任务写在线程的run方法中就行 * 线程每隔一定时间(200ms以内的随机时间)产生一个0~100之间的随机整数 * 打印后将该整数放到集合中,共产生100个整数,全部产生后,睡眠30秒,然后将集合内容打印输出 */class GetData implements Runnable { //因为需要从外界将线程唤醒,需要设置一个标记 private boolean flag = false; public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } @Override public void run() { /* * 该类线程完成的任务 */ //创建一个list集合保存生成的随机数 List<Integer> list = new ArrayList<Integer>(); //需要生成100个随机数 for(int i = 0; i < 100; i++) { //获取随机整数 int randomNum = (int)(Math.random() * 100); //打印随机整数 System.out.println(randomNum); //保存到集合中 list.add(randomNum); //睡觉 try { //获取随机的睡觉时间 long randomTime = (int)(Math.random() * 200); //睡觉 Thread.sleep(randomTime); } catch (InterruptedException e) { //处理睡觉被打断异常 System.out.println("小睡被打断"); } } //当数据生成完成后,将flag修改,便于外界唤醒线程 flag = true; //全部完成后,睡一大觉 try { Thread.sleep(30 * 1000); } catch (InterruptedException e) { System.out.println("长睡被打断"); } //遍历打印集合 for (Integer integer : list) { System.out.print(integer + " "); } }}class Keylisten implements Runnable { //对于对象关联,先写方法,需要什么,就关联什么 //关联两个类 private GetData r; private Thread t; public Keylisten(GetData r, Thread t) { this.r = r; this.t = t; } @Override public void run() { /* * 这个线程要精准的唤醒获取数据的线程 */ while(!((GetData)r).isFlag()) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } t.interrupt(); }}
/** * 银行有一个账户Account包含属性name, balance * 有两个柜台分别同时向同一个账户存3000元,每次存1000,存3次。每次存完打印账户余额。睡眠10毫秒 * * 问题:该程序是否有安全问题,如果有,如何解决? * * 扩展练习 : 一个柜台Deposit存3000元, 每次存1000,存3次 另一个柜台Withdraw取3000元, 每次取1000,取3次 *//* * 一个柜台就是一个线程,将账户与存取钱操作分开 */public class Account { private String name; private int balance; public Account() { } public Account(String name, int balance) { super(); this.name = name; this.balance = balance; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } @Override public String toString() { return "Account [name=" + name + ", balance=" + balance + "]"; }}
/* * 扩展练习 : 一个柜台Deposit存3000元, 每次存1000,存3次 另一个柜台Withdraw取3000元, 每次取1000,取3次 * 有两个柜台分别同时向同一个账户存3000元,每次存1000,存3次。每次存完打印账户余额。睡眠10毫秒 * 每一个柜台相当于一个线程,对于存款,取款操作不同,因此需要不同的线程类 */public class Deposit implements Runnable{ private Account account; public Deposit(Account account) { this.account = account; } @Override public void run() { synchronized ("") { for(int i = 0; i < 3; i++) { account.setBalance((account.getBalance() + 1000)); System.out.println(Thread.currentThread().getName() + " " + "账户余额:" + account.getBalance()); try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println("在睡觉时被打断。"); } } } }}
/* * 取钱柜台也相当于一个线程 * 另一个柜台Withdraw取3000元, 每次取1000,取3次 * 利用使用相同的同步锁将取钱和存钱同步 */public class Withdraw implements Runnable{ private Account account; public Withdraw(Account account) { this.account = account; } @Override public void run() { synchronized ("") { for(int i = 0; i < 3; i++) { account.setBalance(account.getBalance() - 1000); System.out.println(Thread.currentThread().getName() + " " + "账户余额:" + account.getBalance()); try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println("在休息时被打断"); } } } }}
/** * 测试类 * */public class AccountTest { public static void main(String[] args) { Account account = new Account("张三", 5000); Runnable rdeposit = new Deposit(account); Thread td1 = new Thread(rdeposit); td1.setName("存钱柜台A"); td1.start(); Thread td2 = new Thread(rdeposit); td2.setName("存钱柜台B"); td2.start(); Runnable rwithdraw = new Withdraw(account); Thread tw1 = new Thread(rwithdraw); tw1.setName("取钱柜台1"); tw1.start(); }}
2 0
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 线程
- 增删该查——baseDao
- 【CF 706E】Working routine
- 莫队算法,JZOJ1902,【2010集训队出题】小Z的袜子
- html基础标签知识快速回忆
- 自定义HorizontalScrollView嵌套HorizontalListView实现手势监听、按钮监听滑动功能
- 线程
- Mysql 按年度、季度、月度、周、日统计查询的例子
- json
- Git 中忽略某些文件或者文件夹
- 温故知新-进程和线程学习笔记
- (git)You have not concluded your merge (MERGE_HEAD exists).
- Python学习(3): Python 3.x 和 Python 2.x的区别
- Java第一部分
- 日狗一