关于多线程并发的小实验

并发的现象,第一个为参考网上写的,第二个为自己写的

package com.joker.threads.demo;

//这个为转载来的,自己入门用
public class TicketOffice {
private int ticket = 0;
public TicketOffice(int ticketNum){
this.ticket = ticketNum;
}
public int getTicket() {
return ticket;
}
public void setTicket(int ticket) {
this.ticket = ticket;
}
public void sellTicket(){
ticket--;
if(ticket>=0){
System.out.println("售票成功:"+"剩余:"+ticket);
}else {
System.out.println("没有票了");
}
}
public static void main(String[] args) {
final TicketOffice ticketOffice = new TicketOffice(100);
for(int i=0;i<10;i++){
new Thread(){
public void run() {
while (ticketOffice.getTicket()>0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticketOffice.sellTicket();
}
};
}.start(); 
}
}
}

打印结果:


自己写的,模拟的是银行的例子,三条线程,一个存,一个取,一个查

代码如下

package com.joker.threads.demo;


public class Bank {
private int count;


public int getCount() {
return count;
}


public void setCount(int count) {
this.count = count;
}
public Bank(int count){
this.count = count;
}
public void addMoney(int money){
if(count>0){
count = count+money;
System.out.println("存款成功余额为:"+getCount());
}else {
System.out.println("余额小于0,存款失败");
}
}
public void takeMoney(int money){
if(count>0){
count = count-money;
System.out.println("取款成功余额为:"+getCount());
}else {
System.out.println("余额小于0,取款失败");
}
}
public void checkMoney(){
System.out.println("查询金额:"+getCount());
}
public static void main(String[] args) {
final Bank bank = new Bank(100);
ManA a = new ManA(bank);
ManB b = new ManB(bank);
ManC c = new ManC(bank);
for(int i=0;i<10;i++){
// while (true) {
new Thread(a).start();
new Thread(c).start();
new Thread(b).start();
}

}
static class ManA implements Runnable{
private Bank bank;
public ManA(Bank bank){
this.bank = bank;
}
public void run() {
bank.addMoney(10);
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }

}
static class ManB implements Runnable{
private Bank bank;
public ManB(Bank bank){
this.bank = bank;
}
public void run() {
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
bank.takeMoney(10);

}
static class ManC implements Runnable{
private Bank bank;
public ManC(Bank bank){
this.bank = bank;
}
public void run() {
bank.checkMoney();

}
}

结果为:


传统的方法,synz即可解决,更高级的方法,研究中

### 多线程并发服务器的设计与实现 多线程并发服务器是一种常见的高性能服务端架构,其核心在于通过多个线程并行处理客户端请求,从而提升系统的响应能力和吞吐量。以下是关于多线程并发服务器设计与实现的关键要点: #### 1. 基本原理 多线程并发服务器的核心思想是利用操作系统提供的线程机制,在单个进程中创建多个线程来分别处理不同的任务。这种方式能够有效应对I/O密集型任务[^2],因为在某些线程等待I/O操作完成时,其他线程仍可继续工作。 #### 2. 设计模式 一种经典的多线程并发服务器设计方案是基于“主线程监听+子线程处理”的模型。具体而言: - 主线程负责监听来自客户端的连接请求。 - 当收到新的连接请求后,主线程会将其交给一个新的子线程进行处理。 - 子线程独立执行具体的业务逻辑,并最终返回结果给客户端。 这种设计充分利用了现代计算机硬件的多核特性,显著提高了程序性能[^1]。 #### 3. 同步与通信 在多线程环境中,为了避免竞争条件和数据不一致问题,必须采取适当的同步措施。常用的同步工具包括互斥锁(mutex)、信号量(semaphore)以及条件变量(condition variable)。此外,对于需要在线程之间传递消息的情况,则可以通过队列或其他形式的数据结构实现高效通信[^4]。 #### 4. 示例代码 下面是一个简单的多线程TCP服务器示例,展示了如何使用POSIX线程库(pthread)构建基本的服务框架: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <pthread.h> void* handle_client(void* arg) { int client_fd = *(int*)arg; char buffer[1024]; while (1) { memset(buffer, 0, sizeof(buffer)); ssize_t bytes_received = recv(client_fd, buffer, sizeof(buffer), 0); if (bytes_received <= 0) break; // Connection closed or error printf("Received from client: %s\n", buffer); send(client_fd, buffer, strlen(buffer), 0); // Echo back to the client } close(client_fd); free(arg); pthread_exit(NULL); } int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("Socket failed"); exit(EXIT_FAILURE); } if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("Setsockopt failed"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { perror("Bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("Listen failed"); exit(EXIT_FAILURE); } while (1) { if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addrlen)) < 0) { perror("Accept failed"); continue; } int *new_sock = malloc(sizeof(int)); *new_sock = new_socket; pthread_t thread_id; if (pthread_create(&thread_id, NULL, handle_client, (void*)new_sock) != 0) { perror("Thread creation failed"); free(new_sock); } else { pthread_detach(thread_id); // Detach so we don't need to join later } } return 0; } ``` 此代码片段展示了一个基础的多线程TCP服务器,其中每个新建立的连接都会被分配到一个单独的工作线程上进行处理。 #### 5. 性能优化建议 尽管多线程技术提供了良好的扩展性和灵活性,但在实际应用中也需要注意以下几个方面以进一步改善效率: - **线程池**:频繁地创建销毁线程会产生较大的开销,因此推荐引入线程池管理固定数量的工作者线程。 - **异步IO**:针对高负载场景下的大量短时间交互需求,考虑结合异步编程模型减少上下文切换带来的影响[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值