创建并启动一个线程的方法
1) 实现接口的方式
① 写一个具体类, 实现Runnable接口, 并实现其中的run方法,这个run方法就是线程的入口方法
② 创建这个类的对象, 并以这个对象为实参, 创建Thread类的对象
③ 调用Thread对象的start()方法 启动线程
public class ThreadTest {
public static void main(String[] args) {
Runnable r = new PrintEven();
Thread t1 = new Thread(r);
t1.setName("子线程1");
t1.start();
new Thread(()->{
for(i = 0; i < 100; i += 2) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}).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();
}
}
class PrintEven implements Runnable{
private int i ;
@Override
public void run() {
for(i = 0; i < 100; i += 2) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
class 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();
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 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 {
sc.close();
}
}
}
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() {
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);
String string = bfr.readLine();
while(true) {
if(string.equalsIgnoreCase("Q")) {
getRandomNumber.setStopflag(true);
break;
}
string = bfr.readLine();
}
} 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();
Runnable r1 = new Keylisten((GetData)r, t);
Thread t1 = new Thread(r1);
t1.start();
}
}
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<Integer> list = new ArrayList<Integer>();
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 = 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 + "]";
}
}
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("在睡觉时被打断。");
}
}
}
}
}
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();
}
}